]> git.sur5r.net Git - openldap/blob - libraries/libldap/modify.c
Slightly better fix for library cleanup. Requires GCC.
[openldap] / libraries / libldap / modify.c
1 /* $OpenLDAP$ */
2 /*
3  * Copyright 1998-2002 The OpenLDAP Foundation, All Rights Reserved.
4  * COPYING RESTRICTIONS APPLY, see COPYRIGHT file
5  */
6 /*  Portions
7  *  Copyright (c) 1990 Regents of the University of Michigan.
8  *  All rights reserved.
9  *
10  *  modify.c
11  */
12
13 #include "portable.h"
14
15 #include <stdio.h>
16
17 #include <ac/socket.h>
18 #include <ac/string.h>
19 #include <ac/time.h>
20
21 #include "ldap-int.h"
22
23 /*
24  * ldap_modify_ext - initiate an ldap extended modify operation.
25  *
26  * Parameters:
27  *
28  *      ld              LDAP descriptor
29  *      dn              DN of the object to modify
30  *      mods            List of modifications to make.  This is null-terminated
31  *                      array of struct ldapmod's, specifying the modifications
32  *                      to perform.
33  *      sctrls  Server Controls
34  *      cctrls  Client Controls
35  *      msgidp  Message ID pointer
36  *
37  * Example:
38  *      LDAPMod *mods[] = { 
39  *                      { LDAP_MOD_ADD, "cn", { "babs jensen", "babs", 0 } },
40  *                      { LDAP_MOD_REPLACE, "sn", { "jensen", 0 } },
41  *                      0
42  *              }
43  *      rc=  ldap_modify_ext( ld, dn, mods, sctrls, cctrls, &msgid );
44  */
45 int
46 ldap_modify_ext( LDAP *ld,
47         LDAP_CONST char *dn,
48         LDAPMod **mods,
49         LDAPControl **sctrls,
50         LDAPControl **cctrls,
51         int *msgidp )
52 {
53         BerElement      *ber;
54         int             i, rc;
55
56         /*
57          * A modify request looks like this:
58          *      ModifyRequet ::= SEQUENCE {
59          *              object          DistinguishedName,
60          *              modifications   SEQUENCE OF SEQUENCE {
61          *                      operation       ENUMERATED {
62          *                              add     (0),
63          *                              delete  (1),
64          *                              replace (2)
65          *                      },
66          *                      modification    SEQUENCE {
67          *                              type    AttributeType,
68          *                              values  SET OF AttributeValue
69          *                      }
70          *              }
71          *      }
72          */
73
74         Debug( LDAP_DEBUG_TRACE, "ldap_modify_ext\n", 0, 0, 0 );
75
76         /* check client controls */
77         rc = ldap_int_client_controls( ld, cctrls );
78         if( rc != LDAP_SUCCESS ) return rc;
79
80         /* create a message to send */
81         if ( (ber = ldap_alloc_ber_with_options( ld )) == NULL ) {
82                 return( LDAP_NO_MEMORY );
83         }
84
85         if ( ber_printf( ber, "{it{s{" /*}}}*/, ++ld->ld_msgid, LDAP_REQ_MODIFY, dn )
86             == -1 ) {
87                 ld->ld_errno = LDAP_ENCODING_ERROR;
88                 ber_free( ber, 1 );
89                 return( ld->ld_errno );
90         }
91
92         /* for each modification to be performed... */
93         for ( i = 0; mods[i] != NULL; i++ ) {
94                 if (( mods[i]->mod_op & LDAP_MOD_BVALUES) != 0 ) {
95                         rc = ber_printf( ber, "{e{s[V]N}N}",
96                             (ber_int_t) ( mods[i]->mod_op & ~LDAP_MOD_BVALUES ),
97                             mods[i]->mod_type, mods[i]->mod_bvalues );
98                 } else {
99                         rc = ber_printf( ber, "{e{s[v]N}N}",
100                                 (ber_int_t) mods[i]->mod_op,
101                             mods[i]->mod_type, mods[i]->mod_values );
102                 }
103
104                 if ( rc == -1 ) {
105                         ld->ld_errno = LDAP_ENCODING_ERROR;
106                         ber_free( ber, 1 );
107                         return( ld->ld_errno );
108                 }
109         }
110
111         if ( ber_printf( ber, /*{{*/ "N}N}" ) == -1 ) {
112                 ld->ld_errno = LDAP_ENCODING_ERROR;
113                 ber_free( ber, 1 );
114                 return( ld->ld_errno );
115         }
116
117         /* Put Server Controls */
118         if( ldap_int_put_controls( ld, sctrls, ber ) != LDAP_SUCCESS ) {
119                 ber_free( ber, 1 );
120                 return ld->ld_errno;
121         }
122
123         if ( ber_printf( ber, /*{*/ "N}" ) == -1 ) {
124                 ld->ld_errno = LDAP_ENCODING_ERROR;
125                 ber_free( ber, 1 );
126                 return( ld->ld_errno );
127         }
128
129         /* send the message */
130         *msgidp = ldap_send_initial_request( ld, LDAP_REQ_MODIFY, dn, ber );
131         return( *msgidp < 0 ? ld->ld_errno : LDAP_SUCCESS );
132 }
133
134 /*
135  * ldap_modify - initiate an ldap modify operation.
136  *
137  * Parameters:
138  *
139  *      ld              LDAP descriptor
140  *      dn              DN of the object to modify
141  *      mods            List of modifications to make.  This is null-terminated
142  *                      array of struct ldapmod's, specifying the modifications
143  *                      to perform.
144  *
145  * Example:
146  *      LDAPMod *mods[] = { 
147  *                      { LDAP_MOD_ADD, "cn", { "babs jensen", "babs", 0 } },
148  *                      { LDAP_MOD_REPLACE, "sn", { "jensen", 0 } },
149  *                      0
150  *              }
151  *      msgid = ldap_modify( ld, dn, mods );
152  */
153 int
154 ldap_modify( LDAP *ld, LDAP_CONST char *dn, LDAPMod **mods )
155 {
156         int rc, msgid;
157
158         Debug( LDAP_DEBUG_TRACE, "ldap_modify\n", 0, 0, 0 );
159
160         rc = ldap_modify_ext( ld, dn, mods, NULL, NULL, &msgid );
161
162         if ( rc != LDAP_SUCCESS )
163                 return -1;
164
165         return msgid;
166 }
167
168 int
169 ldap_modify_ext_s( LDAP *ld, LDAP_CONST char *dn,
170         LDAPMod **mods, LDAPControl **sctrl, LDAPControl **cctrl )
171 {
172         int             rc;
173         int             msgid;
174         LDAPMessage     *res;
175
176         rc = ldap_modify_ext( ld, dn, mods, sctrl, cctrl, &msgid );
177
178         if ( rc != LDAP_SUCCESS )
179                 return( rc );
180
181         if ( ldap_result( ld, msgid, 1, (struct timeval *) NULL, &res ) == -1 )
182                 return( ld->ld_errno );
183
184         return( ldap_result2error( ld, res, 1 ) );
185 }
186
187 int
188 ldap_modify_s( LDAP *ld, LDAP_CONST char *dn, LDAPMod **mods )
189 {
190         return ldap_modify_ext_s( ld, dn, mods, NULL, NULL );
191 }
192