Back to index

lightning-sunbird  0.9+nobinonly
modify.c
Go to the documentation of this file.
00001 /* ***** BEGIN LICENSE BLOCK *****
00002  * Version: MPL 1.1/GPL 2.0/LGPL 2.1
00003  *
00004  * The contents of this file are subject to the Mozilla Public License Version
00005  * 1.1 (the "License"); you may not use this file except in compliance with
00006  * the License. You may obtain a copy of the License at
00007  * http://www.mozilla.org/MPL/
00008  *
00009  * Software distributed under the License is distributed on an "AS IS" basis,
00010  * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
00011  * for the specific language governing rights and limitations under the
00012  * License.
00013  *
00014  * The Original Code is Mozilla Communicator client code, released
00015  * March 31, 1998.
00016  *
00017  * The Initial Developer of the Original Code is
00018  * Netscape Communications Corporation.
00019  * Portions created by the Initial Developer are Copyright (C) 1998-1999
00020  * the Initial Developer. All Rights Reserved.
00021  *
00022  * Contributor(s):
00023  *
00024  * Alternatively, the contents of this file may be used under the terms of
00025  * either the GNU General Public License Version 2 or later (the "GPL"), or
00026  * the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
00027  * in which case the provisions of the GPL or the LGPL are applicable instead
00028  * of those above. If you wish to allow use of your version of this file only
00029  * under the terms of either the GPL or the LGPL, and not to allow others to
00030  * use your version of this file under the terms of the MPL, indicate your
00031  * decision by deleting the provisions above and replace them with the notice
00032  * and other provisions required by the GPL or the LGPL. If you do not delete
00033  * the provisions above, a recipient may use your version of this file under
00034  * the terms of any one of the MPL, the GPL or the LGPL.
00035  *
00036  * ***** END LICENSE BLOCK ***** */
00037 /*
00038  *  Copyright (c) 1990 Regents of the University of Michigan.
00039  *  All rights reserved.
00040  */
00041 /*
00042  *  modify.c
00043  */
00044 
00045 #if 0
00046 #ifndef lint 
00047 static char copyright[] = "@(#) Copyright (c) 1990 Regents of the University of Michigan.\nAll rights reserved.\n";
00048 #endif
00049 #endif
00050 
00051 #include "ldap-int.h"
00052 
00053 /*
00054  * ldap_modify - initiate an ldap modify operation.  Parameters:
00055  *
00056  *     ld            LDAP descriptor
00057  *     dn            DN of the object to modify
00058  *     mods          List of modifications to make.  This is null-terminated
00059  *                   array of struct ldapmod's, specifying the modifications
00060  *                   to perform.
00061  *
00062  * Example:
00063  *     LDAPMod       *mods[] = { 
00064  *                   { LDAP_MOD_ADD, "cn", { "babs jensen", "babs", 0 } },
00065  *                   { LDAP_MOD_REPLACE, "sn", { "jensen", 0 } },
00066  *                   0
00067  *            }
00068  *     msgid = ldap_modify( ld, dn, mods );
00069  */
00070 int
00071 LDAP_CALL
00072 ldap_modify( LDAP *ld, const char *dn, LDAPMod **mods )
00073 {
00074        int           msgid;
00075 
00076        LDAPDebug( LDAP_DEBUG_TRACE, "ldap_modify\n", 0, 0, 0 );
00077 
00078        if ( ldap_modify_ext( ld, dn, mods, NULL, NULL, &msgid )
00079            == LDAP_SUCCESS ) {
00080               return( msgid );
00081        } else {
00082               return( -1 ); /* error is in ld handle */
00083        }
00084 }
00085 
00086 int
00087 LDAP_CALL
00088 ldap_modify_ext( LDAP *ld, const char *dn, LDAPMod **mods,
00089     LDAPControl **serverctrls, LDAPControl **clientctrls, int *msgidp )
00090 {
00091        BerElement    *ber;
00092        int           i, rc, lderr;
00093 
00094        /*
00095         * A modify request looks like this:
00096         *     ModifyRequet ::= SEQUENCE {
00097         *            object        DistinguishedName,
00098         *            modifications SEQUENCE OF SEQUENCE {
00099         *                   operation     ENUMERATED {
00100         *                          add    (0),
00101         *                          delete (1),
00102         *                          replace       (2)
00103         *                   },
00104         *                   modification  SEQUENCE {
00105         *                          type   AttributeType,
00106         *                          values SET OF AttributeValue
00107         *                   }
00108         *            }
00109         *     }
00110         */
00111 
00112        LDAPDebug( LDAP_DEBUG_TRACE, "ldap_modify_ext\n", 0, 0, 0 );
00113 
00114        if ( !NSLDAPI_VALID_LDAP_POINTER( ld )) {
00115               return( LDAP_PARAM_ERROR );
00116        }
00117        if ( !NSLDAPI_VALID_LDAPMESSAGE_POINTER( msgidp )) 
00118         {
00119               LDAP_SET_LDERRNO( ld, LDAP_PARAM_ERROR, NULL, NULL );
00120               return( LDAP_PARAM_ERROR );
00121        }
00122         
00123        if ( !NSLDAPI_VALID_NONEMPTY_LDAPMOD_ARRAY( mods )) {
00124               lderr = LDAP_PARAM_ERROR;
00125               LDAP_SET_LDERRNO( ld, lderr, NULL, NULL );
00126               return( lderr );
00127        }
00128        if ( dn == NULL ) {
00129               dn = "";
00130        }
00131 
00132        LDAP_MUTEX_LOCK( ld, LDAP_MSGID_LOCK );
00133        *msgidp = ++ld->ld_msgid;
00134        LDAP_MUTEX_UNLOCK( ld, LDAP_MSGID_LOCK );
00135 
00136        /* see if we should add to the cache */
00137        if ( ld->ld_cache_on && ld->ld_cache_modify != NULL ) {
00138               LDAP_MUTEX_LOCK( ld, LDAP_CACHE_LOCK );
00139               if ( (rc = (ld->ld_cache_modify)( ld, *msgidp, LDAP_REQ_MODIFY,
00140                   dn, mods )) != 0 ) {
00141                      *msgidp = rc;
00142                      LDAP_MUTEX_LOCK( ld, LDAP_CACHE_LOCK );
00143                      return( LDAP_SUCCESS );
00144               }
00145               LDAP_MUTEX_UNLOCK( ld, LDAP_CACHE_LOCK );
00146        }
00147 
00148        /* create a message to send */
00149        if (( lderr = nsldapi_alloc_ber_with_options( ld, &ber ))
00150            != LDAP_SUCCESS ) {
00151               return( lderr );
00152        }
00153 
00154        if ( ber_printf( ber, "{it{s{", *msgidp, LDAP_REQ_MODIFY, dn )
00155            == -1 ) {
00156               lderr = LDAP_ENCODING_ERROR;
00157               LDAP_SET_LDERRNO( ld, lderr, NULL, NULL );
00158               ber_free( ber, 1 );
00159               return( lderr );
00160        }
00161 
00162        /* for each modification to be performed... */
00163        for ( i = 0; mods[i] != NULL; i++ ) {
00164               if (( mods[i]->mod_op & LDAP_MOD_BVALUES) != 0 ) {
00165                      rc = ber_printf( ber, "{e{s[V]}}",
00166                          mods[i]->mod_op & ~LDAP_MOD_BVALUES,
00167                          mods[i]->mod_type, mods[i]->mod_bvalues );
00168               } else {
00169                      rc = ber_printf( ber, "{e{s[v]}}", mods[i]->mod_op,
00170                          mods[i]->mod_type, mods[i]->mod_values );
00171               }
00172 
00173               if ( rc == -1 ) {
00174                      lderr = LDAP_ENCODING_ERROR;
00175                      LDAP_SET_LDERRNO( ld, lderr, NULL, NULL );
00176                      ber_free( ber, 1 );
00177                      return( lderr );
00178               }
00179        }
00180 
00181        if ( ber_printf( ber, "}}" ) == -1 ) {
00182               lderr = LDAP_ENCODING_ERROR;
00183               LDAP_SET_LDERRNO( ld, lderr, NULL, NULL );
00184               ber_free( ber, 1 );
00185               return( lderr );
00186        }
00187 
00188        if (( lderr = nsldapi_put_controls( ld, serverctrls, 1, ber ))
00189            != LDAP_SUCCESS ) {
00190               ber_free( ber, 1 );
00191               return( lderr );
00192        }
00193 
00194        /* send the message */
00195        rc = nsldapi_send_initial_request( ld, *msgidp, LDAP_REQ_MODIFY,
00196               (char *)dn, ber );
00197        *msgidp = rc;
00198        return( rc < 0 ? LDAP_GET_LDERRNO( ld, NULL, NULL ) : LDAP_SUCCESS );
00199 }
00200 
00201 int
00202 LDAP_CALL
00203 ldap_modify_s( LDAP *ld, const char *dn, LDAPMod **mods )
00204 {
00205        return( ldap_modify_ext_s( ld, dn, mods, NULL, NULL ));
00206 }
00207 
00208 int
00209 LDAP_CALL
00210 ldap_modify_ext_s( LDAP *ld, const char *dn, LDAPMod **mods,
00211     LDAPControl **serverctrls, LDAPControl **clientctrls )
00212 {
00213        int           msgid, err;
00214        LDAPMessage   *res;
00215 
00216        if (( err = ldap_modify_ext( ld, dn, mods, serverctrls, clientctrls,
00217            &msgid )) != LDAP_SUCCESS ) {
00218               return( err );
00219        }
00220 
00221        if ( ldap_result( ld, msgid, 1, (struct timeval *)NULL, &res ) == -1 ) {
00222               return( LDAP_GET_LDERRNO( ld, NULL, NULL ) );
00223        }
00224 
00225        return( ldap_result2error( ld, res, 1 ) );
00226 }