]> git.sur5r.net Git - openldap/blob - libraries/libldap/modify.c
7bbfc794290afccdb9f991a13857ff133fa5e28e
[openldap] / libraries / libldap / modify.c
1 /* $OpenLDAP$ */
2 /* This work is part of OpenLDAP Software <http://www.openldap.org/>.
3  *
4  * Copyright 1998-2015 The OpenLDAP Foundation.
5  * All rights reserved.
6  *
7  * Redistribution and use in source and binary forms, with or without
8  * modification, are permitted only as authorized by the OpenLDAP
9  * Public License.
10  *
11  * A copy of this license is available in the file LICENSE in the
12  * top-level directory of the distribution or, alternatively, at
13  * <http://www.OpenLDAP.org/license.html>.
14  */
15 /* Portions Copyright (c) 1990 Regents of the University of Michigan.
16  * All rights reserved.
17  */
18
19 #include "portable.h"
20
21 #include <stdio.h>
22
23 #include <ac/socket.h>
24 #include <ac/string.h>
25 #include <ac/time.h>
26
27 #include "ldap-int.h"
28
29 /* A modify request/response looks like this:
30  *        ModifyRequest ::= [APPLICATION 6] SEQUENCE {              
31  *             object          LDAPDN,
32  *             changes         SEQUENCE OF change SEQUENCE {
33  *                  operation       ENUMERATED {      
34  *                       add     (0),                
35  *                       delete  (1),                 
36  *                       replace (2),
37  *                       ...  },
38  *                  modification    PartialAttribute } }                  
39  *
40  *        PartialAttribute ::= SEQUENCE {
41  *             type       AttributeDescription,
42  *             vals       SET OF value AttributeValue }
43  *
44  *        AttributeDescription ::= LDAPString           
45  *              -- Constrained to <attributedescription> [RFC4512]
46  *                                      
47  *        AttributeValue ::= OCTET STRING
48  *              
49  *        ModifyResponse ::= [APPLICATION 7] LDAPResult
50  *
51  * (Source: RFC 4511)
52  */
53
54 BerElement *
55 ldap_build_modify_req(
56         LDAP *ld,
57         LDAP_CONST char *dn,
58         LDAPMod **mods,
59         LDAPControl **sctrls,
60         LDAPControl **cctrls,
61         ber_int_t *msgidp )
62 {
63         BerElement      *ber;
64         int             i, rc;
65
66         /* create a message to send */
67         if ( (ber = ldap_alloc_ber_with_options( ld )) == NULL ) {
68                 return( NULL );
69         }
70
71         LDAP_NEXT_MSGID( ld, *msgidp );
72         rc = ber_printf( ber, "{it{s{" /*}}}*/, *msgidp, LDAP_REQ_MODIFY, dn );
73         if ( rc == -1 ) {
74                 ld->ld_errno = LDAP_ENCODING_ERROR;
75                 ber_free( ber, 1 );
76                 return( NULL );
77         }
78
79         /* allow mods to be NULL ("touch") */
80         if ( mods ) {
81                 /* for each modification to be performed... */
82                 for ( i = 0; mods[i] != NULL; i++ ) {
83                         if (( mods[i]->mod_op & LDAP_MOD_BVALUES) != 0 ) {
84                                 rc = ber_printf( ber, "{e{s[V]N}N}",
85                                     (ber_int_t) ( mods[i]->mod_op & ~LDAP_MOD_BVALUES ),
86                                     mods[i]->mod_type, mods[i]->mod_bvalues );
87                         } else {
88                                 rc = ber_printf( ber, "{e{s[v]N}N}",
89                                         (ber_int_t) mods[i]->mod_op,
90                                     mods[i]->mod_type, mods[i]->mod_values );
91                         }
92
93                         if ( rc == -1 ) {
94                                 ld->ld_errno = LDAP_ENCODING_ERROR;
95                                 ber_free( ber, 1 );
96                                 return( NULL );
97                         }
98                 }
99         }
100
101         if ( ber_printf( ber, /*{{*/ "N}N}" ) == -1 ) {
102                 ld->ld_errno = LDAP_ENCODING_ERROR;
103                 ber_free( ber, 1 );
104                 return( NULL );
105         }
106
107         /* Put Server Controls */
108         if( ldap_int_put_controls( ld, sctrls, ber ) != LDAP_SUCCESS ) {
109                 ber_free( ber, 1 );
110                 return( NULL );
111         }
112
113         if ( ber_printf( ber, /*{*/ "N}" ) == -1 ) {
114                 ld->ld_errno = LDAP_ENCODING_ERROR;
115                 ber_free( ber, 1 );
116                 return( NULL );
117         }
118
119         return( ber );
120 }
121
122 /*
123  * ldap_modify_ext - initiate an ldap extended modify operation.
124  *
125  * Parameters:
126  *
127  *      ld              LDAP descriptor
128  *      dn              DN of the object to modify
129  *      mods            List of modifications to make.  This is null-terminated
130  *                      array of struct ldapmod's, specifying the modifications
131  *                      to perform.
132  *      sctrls  Server Controls
133  *      cctrls  Client Controls
134  *      msgidp  Message ID pointer
135  *
136  * Example:
137  *      LDAPMod *mods[] = {
138  *                      { LDAP_MOD_ADD, "cn", { "babs jensen", "babs", 0 } },
139  *                      { LDAP_MOD_REPLACE, "sn", { "babs jensen", "babs", 0 } },
140  *                      { LDAP_MOD_DELETE, "ou", 0 },
141  *                      { LDAP_MOD_INCREMENT, "uidNumber, { "1", 0 } }
142  *                      0
143  *              }
144  *      rc=  ldap_modify_ext( ld, dn, mods, sctrls, cctrls, &msgid );
145  */
146 int
147 ldap_modify_ext( LDAP *ld,
148         LDAP_CONST char *dn,
149         LDAPMod **mods,
150         LDAPControl **sctrls,
151         LDAPControl **cctrls,
152         int *msgidp )
153 {
154         BerElement      *ber;
155         int             i, rc;
156         ber_int_t       id;
157
158         Debug( LDAP_DEBUG_TRACE, "ldap_modify_ext\n", 0, 0, 0 );
159
160         /* check client controls */
161         rc = ldap_int_client_controls( ld, cctrls );
162         if( rc != LDAP_SUCCESS ) return rc;
163
164         ber = ldap_build_modify_req( ld, dn, mods, sctrls, cctrls, &id );
165         if( !ber )
166                 return ld->ld_errno;
167
168         /* send the message */
169         *msgidp = ldap_send_initial_request( ld, LDAP_REQ_MODIFY, dn, ber, id );
170         return( *msgidp < 0 ? ld->ld_errno : LDAP_SUCCESS );
171 }
172
173 /*
174  * ldap_modify - initiate an ldap modify operation.
175  *
176  * Parameters:
177  *
178  *      ld              LDAP descriptor
179  *      dn              DN of the object to modify
180  *      mods            List of modifications to make.  This is null-terminated
181  *                      array of struct ldapmod's, specifying the modifications
182  *                      to perform.
183  *
184  * Example:
185  *      LDAPMod *mods[] = {
186  *                      { LDAP_MOD_ADD, "cn", { "babs jensen", "babs", 0 } },
187  *                      { LDAP_MOD_REPLACE, "sn", { "babs jensen", "babs", 0 } },
188  *                      { LDAP_MOD_DELETE, "ou", 0 },
189  *                      { LDAP_MOD_INCREMENT, "uidNumber, { "1", 0 } }
190  *                      0
191  *              }
192  *      msgid = ldap_modify( ld, dn, mods );
193  */
194 int
195 ldap_modify( LDAP *ld, LDAP_CONST char *dn, LDAPMod **mods )
196 {
197         int rc, msgid;
198
199         Debug( LDAP_DEBUG_TRACE, "ldap_modify\n", 0, 0, 0 );
200
201         rc = ldap_modify_ext( ld, dn, mods, NULL, NULL, &msgid );
202
203         if ( rc != LDAP_SUCCESS )
204                 return -1;
205
206         return msgid;
207 }
208
209 int
210 ldap_modify_ext_s( LDAP *ld, LDAP_CONST char *dn,
211         LDAPMod **mods, LDAPControl **sctrl, LDAPControl **cctrl )
212 {
213         int             rc;
214         int             msgid;
215         LDAPMessage     *res;
216
217         rc = ldap_modify_ext( ld, dn, mods, sctrl, cctrl, &msgid );
218
219         if ( rc != LDAP_SUCCESS )
220                 return( rc );
221
222         if ( ldap_result( ld, msgid, LDAP_MSG_ALL, (struct timeval *) NULL, &res ) == -1 || !res )
223                 return( ld->ld_errno );
224
225         return( ldap_result2error( ld, res, 1 ) );
226 }
227
228 int
229 ldap_modify_s( LDAP *ld, LDAP_CONST char *dn, LDAPMod **mods )
230 {
231         return ldap_modify_ext_s( ld, dn, mods, NULL, NULL );
232 }
233