Back to index

openldap  2.4.31
modify.c
Go to the documentation of this file.
00001 /* $OpenLDAP$ */
00002 /* This work is part of OpenLDAP Software <http://www.openldap.org/>.
00003  *
00004  * Copyright 1998-2012 The OpenLDAP Foundation.
00005  * All rights reserved.
00006  *
00007  * Redistribution and use in source and binary forms, with or without
00008  * modification, are permitted only as authorized by the OpenLDAP
00009  * Public License.
00010  *
00011  * A copy of this license is available in the file LICENSE in the
00012  * top-level directory of the distribution or, alternatively, at
00013  * <http://www.OpenLDAP.org/license.html>.
00014  */
00015 /* Portions Copyright (c) 1990 Regents of the University of Michigan.
00016  * All rights reserved.
00017  */
00018 
00019 #include "portable.h"
00020 
00021 #include <stdio.h>
00022 
00023 #include <ac/socket.h>
00024 #include <ac/string.h>
00025 #include <ac/time.h>
00026 
00027 #include "ldap-int.h"
00028 
00029 /* A modify request/response looks like this:
00030  *        ModifyRequest ::= [APPLICATION 6] SEQUENCE {              
00031  *             object          LDAPDN,
00032  *             changes         SEQUENCE OF change SEQUENCE {
00033  *                  operation       ENUMERATED {      
00034  *                       add     (0),                
00035  *                       delete  (1),                 
00036  *                       replace (2),
00037  *                       ...  },
00038  *                  modification    PartialAttribute } }                  
00039  *
00040  *        PartialAttribute ::= SEQUENCE {
00041  *             type       AttributeDescription,
00042  *             vals       SET OF value AttributeValue }
00043  *
00044  *        AttributeDescription ::= LDAPString           
00045  *              -- Constrained to <attributedescription> [RFC4512]
00046  *                                      
00047  *        AttributeValue ::= OCTET STRING
00048  *            
00049  *        ModifyResponse ::= [APPLICATION 7] LDAPResult
00050  *
00051  * (Source: RFC 4511)
00052  */
00053 
00054 
00055 /*
00056  * ldap_modify_ext - initiate an ldap extended modify operation.
00057  *
00058  * Parameters:
00059  *
00060  *     ld            LDAP descriptor
00061  *     dn            DN of the object to modify
00062  *     mods          List of modifications to make.  This is null-terminated
00063  *                   array of struct ldapmod's, specifying the modifications
00064  *                   to perform.
00065  *     sctrls Server Controls
00066  *     cctrls Client Controls
00067  *     msgidp Message ID pointer
00068  *
00069  * Example:
00070  *     LDAPMod       *mods[] = { 
00071  *                   { LDAP_MOD_ADD, "cn", { "babs jensen", "babs", 0 } },
00072  *                   { LDAP_MOD_REPLACE, "sn", { "babs jensen", "babs", 0 } },
00073  *                   { LDAP_MOD_DELETE, "ou", 0 },
00074  *                   { LDAP_MOD_INCREMENT, "uidNumber, { "1", 0 } }
00075  *                   0
00076  *            }
00077  *     rc=  ldap_modify_ext( ld, dn, mods, sctrls, cctrls, &msgid );
00078  */
00079 int
00080 ldap_modify_ext( LDAP *ld,
00081        LDAP_CONST char *dn,
00082        LDAPMod **mods,
00083        LDAPControl **sctrls,
00084        LDAPControl **cctrls,
00085        int *msgidp )
00086 {
00087        BerElement    *ber;
00088        int           i, rc;
00089        ber_int_t     id;
00090 
00091        Debug( LDAP_DEBUG_TRACE, "ldap_modify_ext\n", 0, 0, 0 );
00092 
00093        /* check client controls */
00094        rc = ldap_int_client_controls( ld, cctrls );
00095        if( rc != LDAP_SUCCESS ) return rc;
00096 
00097        /* create a message to send */
00098        if ( (ber = ldap_alloc_ber_with_options( ld )) == NULL ) {
00099               return( LDAP_NO_MEMORY );
00100        }
00101 
00102        LDAP_NEXT_MSGID( ld, id );
00103        rc = ber_printf( ber, "{it{s{" /*}}}*/, id, LDAP_REQ_MODIFY, dn );
00104        if ( rc == -1 ) {
00105               ld->ld_errno = LDAP_ENCODING_ERROR;
00106               ber_free( ber, 1 );
00107               return( ld->ld_errno );
00108        }
00109 
00110        /* allow mods to be NULL ("touch") */
00111        if ( mods ) {
00112               /* for each modification to be performed... */
00113               for ( i = 0; mods[i] != NULL; i++ ) {
00114                      if (( mods[i]->mod_op & LDAP_MOD_BVALUES) != 0 ) {
00115                             rc = ber_printf( ber, "{e{s[V]N}N}",
00116                                 (ber_int_t) ( mods[i]->mod_op & ~LDAP_MOD_BVALUES ),
00117                                 mods[i]->mod_type, mods[i]->mod_bvalues );
00118                      } else {
00119                             rc = ber_printf( ber, "{e{s[v]N}N}",
00120                                    (ber_int_t) mods[i]->mod_op,
00121                                 mods[i]->mod_type, mods[i]->mod_values );
00122                      }
00123 
00124                      if ( rc == -1 ) {
00125                             ld->ld_errno = LDAP_ENCODING_ERROR;
00126                             ber_free( ber, 1 );
00127                             return( ld->ld_errno );
00128                      }
00129               }
00130        }
00131 
00132        if ( ber_printf( ber, /*{{*/ "N}N}" ) == -1 ) {
00133               ld->ld_errno = LDAP_ENCODING_ERROR;
00134               ber_free( ber, 1 );
00135               return( ld->ld_errno );
00136        }
00137 
00138        /* Put Server Controls */
00139        if( ldap_int_put_controls( ld, sctrls, ber ) != LDAP_SUCCESS ) {
00140               ber_free( ber, 1 );
00141               return ld->ld_errno;
00142        }
00143 
00144        if ( ber_printf( ber, /*{*/ "N}" ) == -1 ) {
00145               ld->ld_errno = LDAP_ENCODING_ERROR;
00146               ber_free( ber, 1 );
00147               return( ld->ld_errno );
00148        }
00149 
00150        /* send the message */
00151        *msgidp = ldap_send_initial_request( ld, LDAP_REQ_MODIFY, dn, ber, id );
00152        return( *msgidp < 0 ? ld->ld_errno : LDAP_SUCCESS );
00153 }
00154 
00155 /*
00156  * ldap_modify - initiate an ldap modify operation.
00157  *
00158  * Parameters:
00159  *
00160  *     ld            LDAP descriptor
00161  *     dn            DN of the object to modify
00162  *     mods          List of modifications to make.  This is null-terminated
00163  *                   array of struct ldapmod's, specifying the modifications
00164  *                   to perform.
00165  *
00166  * Example:
00167  *     LDAPMod       *mods[] = { 
00168  *                   { LDAP_MOD_ADD, "cn", { "babs jensen", "babs", 0 } },
00169  *                   { LDAP_MOD_REPLACE, "sn", { "babs jensen", "babs", 0 } },
00170  *                   { LDAP_MOD_DELETE, "ou", 0 },
00171  *                   { LDAP_MOD_INCREMENT, "uidNumber, { "1", 0 } }
00172  *                   0
00173  *            }
00174  *     msgid = ldap_modify( ld, dn, mods );
00175  */
00176 int
00177 ldap_modify( LDAP *ld, LDAP_CONST char *dn, LDAPMod **mods )
00178 {
00179        int rc, msgid;
00180 
00181        Debug( LDAP_DEBUG_TRACE, "ldap_modify\n", 0, 0, 0 );
00182 
00183        rc = ldap_modify_ext( ld, dn, mods, NULL, NULL, &msgid );
00184 
00185        if ( rc != LDAP_SUCCESS )
00186               return -1;
00187 
00188        return msgid;
00189 }
00190 
00191 int
00192 ldap_modify_ext_s( LDAP *ld, LDAP_CONST char *dn,
00193        LDAPMod **mods, LDAPControl **sctrl, LDAPControl **cctrl )
00194 {
00195        int           rc;
00196        int           msgid;
00197        LDAPMessage   *res;
00198 
00199        rc = ldap_modify_ext( ld, dn, mods, sctrl, cctrl, &msgid );
00200 
00201        if ( rc != LDAP_SUCCESS )
00202               return( rc );
00203 
00204        if ( ldap_result( ld, msgid, LDAP_MSG_ALL, (struct timeval *) NULL, &res ) == -1 || !res )
00205               return( ld->ld_errno );
00206 
00207        return( ldap_result2error( ld, res, 1 ) );
00208 }
00209 
00210 int
00211 ldap_modify_s( LDAP *ld, LDAP_CONST char *dn, LDAPMod **mods )
00212 {
00213        return ldap_modify_ext_s( ld, dn, mods, NULL, NULL );
00214 }
00215