]> git.sur5r.net Git - openldap/blob - libraries/libldap/modify.c
Sync with HEAD
[openldap] / libraries / libldap / modify.c
1 /* $OpenLDAP$ */
2 /* This work is part of OpenLDAP Software <http://www.openldap.org/>.
3  *
4  * Copyright 1998-2003 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 /* Portions Copyright (C) The Internet Society (1997)
19  * ASN.1 fragments are from RFC 2251; see RFC for full legal notices.
20  */
21
22 #include "portable.h"
23
24 #include <stdio.h>
25
26 #include <ac/socket.h>
27 #include <ac/string.h>
28 #include <ac/time.h>
29
30 #include "ldap-int.h"
31
32 /*
33  * ldap_modify_ext - initiate an ldap extended modify operation.
34  *
35  * Parameters:
36  *
37  *      ld              LDAP descriptor
38  *      dn              DN of the object to modify
39  *      mods            List of modifications to make.  This is null-terminated
40  *                      array of struct ldapmod's, specifying the modifications
41  *                      to perform.
42  *      sctrls  Server Controls
43  *      cctrls  Client Controls
44  *      msgidp  Message ID pointer
45  *
46  * Example:
47  *      LDAPMod *mods[] = { 
48  *                      { LDAP_MOD_ADD, "cn", { "babs jensen", "babs", 0 } },
49  *                      { LDAP_MOD_REPLACE, "sn", { "babs jensen", "babs", 0 } },
50  *                      { LDAP_MOD_DELETE, "ou", 0 },
51  *                      { LDAP_MOD_INCREMENT, "uidNumber, { "1", 0 } }
52  *                      0
53  *              }
54  *      rc=  ldap_modify_ext( ld, dn, mods, sctrls, cctrls, &msgid );
55  */
56 int
57 ldap_modify_ext( LDAP *ld,
58         LDAP_CONST char *dn,
59         LDAPMod **mods,
60         LDAPControl **sctrls,
61         LDAPControl **cctrls,
62         int *msgidp )
63 {
64         BerElement      *ber;
65         int             i, rc;
66         ber_int_t       id;
67
68         /*
69          * A modify request looks like this:
70          *      ModifyRequet ::= SEQUENCE {
71          *              object          DistinguishedName,
72          *              modifications   SEQUENCE OF SEQUENCE {
73          *                      operation       ENUMERATED {
74          *                              add     (0),
75          *                              delete (1),
76          *                              replace (2),
77          *                              increment (3) -- extension
78          *                      },
79          *                      modification    SEQUENCE {
80          *                              type    AttributeType,
81          *                              values  SET OF AttributeValue
82          *                      }
83          *              }
84          *      }
85          */
86
87 #ifdef NEW_LOGGING
88         LDAP_LOG ( OPERATION, ENTRY, "ldap_modify_ext\n", 0, 0, 0 );
89 #else
90         Debug( LDAP_DEBUG_TRACE, "ldap_modify_ext\n", 0, 0, 0 );
91 #endif
92
93         /* check client controls */
94         rc = ldap_int_client_controls( ld, cctrls );
95         if( rc != LDAP_SUCCESS ) return rc;
96
97         /* create a message to send */
98         if ( (ber = ldap_alloc_ber_with_options( ld )) == NULL ) {
99                 return( LDAP_NO_MEMORY );
100         }
101
102         LDAP_NEXT_MSGID( ld, id );
103         rc = ber_printf( ber, "{it{s{" /*}}}*/, id, LDAP_REQ_MODIFY, dn );
104         if ( rc == -1 ) {
105                 ld->ld_errno = LDAP_ENCODING_ERROR;
106                 ber_free( ber, 1 );
107                 return( ld->ld_errno );
108         }
109
110         /* for each modification to be performed... */
111         for ( i = 0; mods[i] != NULL; i++ ) {
112                 if (( mods[i]->mod_op & LDAP_MOD_BVALUES) != 0 ) {
113                         rc = ber_printf( ber, "{e{s[V]N}N}",
114                             (ber_int_t) ( mods[i]->mod_op & ~LDAP_MOD_BVALUES ),
115                             mods[i]->mod_type, mods[i]->mod_bvalues );
116                 } else {
117                         rc = ber_printf( ber, "{e{s[v]N}N}",
118                                 (ber_int_t) mods[i]->mod_op,
119                             mods[i]->mod_type, mods[i]->mod_values );
120                 }
121
122                 if ( rc == -1 ) {
123                         ld->ld_errno = LDAP_ENCODING_ERROR;
124                         ber_free( ber, 1 );
125                         return( ld->ld_errno );
126                 }
127         }
128
129         if ( ber_printf( ber, /*{{*/ "N}N}" ) == -1 ) {
130                 ld->ld_errno = LDAP_ENCODING_ERROR;
131                 ber_free( ber, 1 );
132                 return( ld->ld_errno );
133         }
134
135         /* Put Server Controls */
136         if( ldap_int_put_controls( ld, sctrls, ber ) != LDAP_SUCCESS ) {
137                 ber_free( ber, 1 );
138                 return ld->ld_errno;
139         }
140
141         if ( ber_printf( ber, /*{*/ "N}" ) == -1 ) {
142                 ld->ld_errno = LDAP_ENCODING_ERROR;
143                 ber_free( ber, 1 );
144                 return( ld->ld_errno );
145         }
146
147         /* send the message */
148         *msgidp = ldap_send_initial_request( ld, LDAP_REQ_MODIFY, dn, ber, id );
149         return( *msgidp < 0 ? ld->ld_errno : LDAP_SUCCESS );
150 }
151
152 /*
153  * ldap_modify - initiate an ldap modify operation.
154  *
155  * Parameters:
156  *
157  *      ld              LDAP descriptor
158  *      dn              DN of the object to modify
159  *      mods            List of modifications to make.  This is null-terminated
160  *                      array of struct ldapmod's, specifying the modifications
161  *                      to perform.
162  *
163  * Example:
164  *      LDAPMod *mods[] = { 
165  *                      { LDAP_MOD_ADD, "cn", { "babs jensen", "babs", 0 } },
166  *                      { LDAP_MOD_REPLACE, "sn", { "babs jensen", "babs", 0 } },
167  *                      { LDAP_MOD_DELETE, "ou", 0 },
168  *                      { LDAP_MOD_INCREMENT, "uidNumber, { "1", 0 } }
169  *                      0
170  *              }
171  *      msgid = ldap_modify( ld, dn, mods );
172  */
173 int
174 ldap_modify( LDAP *ld, LDAP_CONST char *dn, LDAPMod **mods )
175 {
176         int rc, msgid;
177
178 #ifdef NEW_LOGGING
179         LDAP_LOG ( OPERATION, ENTRY, "ldap_modify\n", 0, 0, 0 );
180 #else
181         Debug( LDAP_DEBUG_TRACE, "ldap_modify\n", 0, 0, 0 );
182 #endif
183
184         rc = ldap_modify_ext( ld, dn, mods, NULL, NULL, &msgid );
185
186         if ( rc != LDAP_SUCCESS )
187                 return -1;
188
189         return msgid;
190 }
191
192 int
193 ldap_modify_ext_s( LDAP *ld, LDAP_CONST char *dn,
194         LDAPMod **mods, LDAPControl **sctrl, LDAPControl **cctrl )
195 {
196         int             rc;
197         int             msgid;
198         LDAPMessage     *res;
199
200         rc = ldap_modify_ext( ld, dn, mods, sctrl, cctrl, &msgid );
201
202         if ( rc != LDAP_SUCCESS )
203                 return( rc );
204
205         if ( ldap_result( ld, msgid, 1, (struct timeval *) NULL, &res ) == -1 )
206                 return( ld->ld_errno );
207
208         return( ldap_result2error( ld, res, 1 ) );
209 }
210
211 int
212 ldap_modify_s( LDAP *ld, LDAP_CONST char *dn, LDAPMod **mods )
213 {
214         return ldap_modify_ext_s( ld, dn, mods, NULL, NULL );
215 }
216