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