1 /*
2 * Portions Copyright 1998 Sun Microsystems, Inc. All rights reserved.
3 * Use is subject to license terms.
4 */
5
6 #pragma ident "%Z%%M% %I% %E% SMI"
7
8 /*
9 * Copyright (c) 1990 Regents of the University of Michigan.
10 * All rights reserved.
11 *
12 * modify.c
13 */
14
15 #ifndef lint
16 static char copyright[] = "@(#) Copyright (c) 1990 Regents of the University of Michigan.\nAll rights reserved.\n";
17 #endif
18
19 #include <stdio.h>
20 #include <string.h>
21
22 #ifdef MACOS
23 #include "macos.h"
24 #endif /* MACOS */
25
26 #if !defined( MACOS ) && !defined( DOS )
27 #include <sys/types.h>
28 #include <sys/socket.h>
29 #endif
30
31 #include "lber.h"
32 #include "ldap.h"
33 #include "ldap-private.h"
34 #include "ldap-int.h"
35
ldap_build_modify_req(LDAP * ld,char * dn,LDAPMod ** mods,LDAPControl ** serverctrls)36 BerElement * ldap_build_modify_req(LDAP *ld, char *dn, LDAPMod ** mods, LDAPControl **serverctrls)
37 {
38 BerElement *ber;
39 int i, rc;
40
41 /*
42 * A modify request looks like this:
43 * ModifyRequest ::= SEQUENCE {
44 * object DistinguishedName,
45 * modifications SEQUENCE OF SEQUENCE {
46 * operation ENUMERATED {
47 * add (0),
48 * delete (1),
49 * replace (2)
50 * },
51 * modification SEQUENCE {
52 * type AttributeType,
53 * values SET OF AttributeValue
54 * }
55 * }
56 * }
57 */
58 /* create a message to send */
59 if ( (ber = alloc_ber_with_options( ld )) == NULLBER ) {
60 return( NULLBER );
61 }
62 if ( ber_printf( ber, "{it{s{", ++ld->ld_msgid, LDAP_REQ_MODIFY, dn )
63 == -1 ) {
64 ld->ld_errno = LDAP_ENCODING_ERROR;
65 ber_free( ber, 1 );
66 return( NULLBER );
67 }
68
69 /* for each modification to be performed... */
70 for ( i = 0; mods[i] != NULL; i++ ) {
71 if (( mods[i]->mod_op & LDAP_MOD_BVALUES) != 0 ) {
72 rc = ber_printf( ber, "{e{s[V]}}",
73 mods[i]->mod_op & ~LDAP_MOD_BVALUES,
74 mods[i]->mod_type, mods[i]->mod_bvalues );
75 } else {
76 rc = ber_printf( ber, "{e{s[v]}}", mods[i]->mod_op,
77 mods[i]->mod_type, mods[i]->mod_values );
78 }
79
80 if ( rc == -1 ) {
81 ld->ld_errno = LDAP_ENCODING_ERROR;
82 ber_free( ber, 1 );
83 return( NULLBER );
84 }
85 }
86
87 if ( ber_printf( ber, "}}" ) == -1 ) {
88 ld->ld_errno = LDAP_ENCODING_ERROR;
89 ber_free( ber, 1 );
90 return( NULLBER );
91 }
92
93 /* LDAPv3 */
94 /* Code controls if any */
95 if (serverctrls && serverctrls[0]) {
96 if (ldap_controls_code(ber, serverctrls) != LDAP_SUCCESS){
97 ld->ld_errno = LDAP_ENCODING_ERROR;
98 ber_free( ber, 1 );
99 return( NULLBER );
100 }
101 } else if (ld->ld_srvctrls && ld->ld_srvctrls[0]) {
102 /* Otherwise, is there any global server ctrls ? */
103 if (ldap_controls_code(ber, ld->ld_srvctrls) != LDAP_SUCCESS){
104 ld->ld_errno = LDAP_ENCODING_ERROR;
105 ber_free( ber, 1 );
106 return( NULLBER );
107 }
108 }
109
110 if ( ber_printf( ber, "}" ) == -1 ) {
111 ld->ld_errno = LDAP_ENCODING_ERROR;
112 ber_free( ber, 1 );
113 return( NULLBER );
114 }
115 return (ber);
116 }
117
118 /*
119 * ldap_modify - initiate an ldap (and X.500) modify operation. Parameters:
120 *
121 * ld LDAP descriptor
122 * dn DN of the object to modify
123 * mods List of modifications to make. This is null-terminated
124 * array of struct ldapmod's, specifying the modifications
125 * to perform.
126 *
127 * Example:
128 * LDAPMod *mods[] = {
129 * { LDAP_MOD_ADD, "cn", { "babs jensen", "babs", 0 } },
130 * { LDAP_MOD_REPLACE, "sn", { "jensen", 0 } },
131 * 0
132 * }
133 * msgid = ldap_modify( ld, dn, mods );
134 */
135 int
ldap_modify(LDAP * ld,char * dn,LDAPMod ** mods)136 ldap_modify( LDAP *ld, char *dn, LDAPMod **mods )
137 {
138 BerElement *ber;
139 int rv;
140
141 #ifdef _REENTRANT
142 LOCK_LDAP(ld);
143 #endif
144
145 Debug( LDAP_DEBUG_TRACE, catgets(slapdcat, 1, 192, "ldap_modify\n"), 0, 0, 0 );
146
147 if ((ber = ldap_build_modify_req(ld, dn, mods, NULL)) == NULLBER){
148 #ifdef _REENTRANT
149 UNLOCK_LDAP(ld);
150 #endif
151 return (-1);
152 }
153
154 /* send the message */
155 rv = send_initial_request( ld, LDAP_REQ_MODIFY, dn, ber );
156 #ifdef _REENTRANT
157 UNLOCK_LDAP(ld);
158 #endif
159 return ( rv );
160 }
161
162 int
ldap_modify_s(LDAP * ld,char * dn,LDAPMod ** mods)163 ldap_modify_s( LDAP *ld, char *dn, LDAPMod **mods )
164 {
165 int msgid;
166 LDAPMessage *res;
167
168 if ( (msgid = ldap_modify( ld, dn, mods )) == -1 )
169 return( ld->ld_errno );
170
171 if ( ldap_result( ld, msgid, 1, (struct timeval *) NULL, &res ) == -1 )
172 return( ld->ld_errno );
173
174 return( ldap_result2error( ld, res, 1 ) );
175 }
176
177 /* ldapv3 API extensions */
178
ldap_modify_ext(LDAP * ld,char * dn,LDAPMod ** mods,LDAPControl ** serverctrls,LDAPControl ** clientctrls,int * msgidp)179 int ldap_modify_ext(LDAP *ld, char *dn, LDAPMod **mods,
180 LDAPControl **serverctrls, LDAPControl **clientctrls, int *msgidp)
181 {
182 BerElement *ber;
183 int i, rc;
184 int rv;
185
186 #ifdef _REENTRANT
187 LOCK_LDAP(ld);
188 #endif
189
190 Debug( LDAP_DEBUG_TRACE, catgets(slapdcat, 1, 192, "ldap_modify\n"), 0, 0, 0 );
191
192 if ((ber = ldap_build_modify_req(ld, dn, mods, serverctrls)) == NULLBER){
193 rv = ld->ld_errno;
194 if (rv == LDAP_SUCCESS)
195 rv = LDAP_OTHER;
196 #ifdef _REENTRANT
197 UNLOCK_LDAP(ld);
198 #endif
199 return (rv);
200 }
201
202 /* send the message */
203 rv = send_initial_request( ld, LDAP_REQ_MODIFY, dn, ber );
204 if (rv == -1){
205 rv = ld->ld_errno;
206 if (rv == LDAP_SUCCESS){
207 rv = LDAP_OTHER;
208 }
209 #ifdef _REENTRANT
210 UNLOCK_LDAP(ld);
211 #endif
212 return (rv);
213 }
214 *msgidp = rv;
215 #ifdef _REENTRANT
216 UNLOCK_LDAP(ld);
217 #endif
218 return ( LDAP_SUCCESS );
219 }
220
221
ldap_modify_ext_s(LDAP * ld,char * dn,LDAPMod ** mods,LDAPControl ** serverctrls,LDAPControl ** clientctrls)222 int ldap_modify_ext_s(LDAP *ld, char *dn, LDAPMod **mods,
223 LDAPControl **serverctrls, LDAPControl **clientctrls)
224 {
225 int msgid;
226 int retcode = LDAP_SUCCESS;
227 LDAPMessage *res;
228
229 if ((retcode = ldap_modify_ext(ld, dn, mods, serverctrls, clientctrls, &msgid)) != LDAP_SUCCESS)
230 return (retcode);
231 if (ldap_result(ld, msgid, 1, (struct timeval *)NULL, &res ) == -1)
232 return (ld->ld_errno );
233
234 #ifdef _REENTRANT
235 LOCK_LDAP(ld);
236 #endif
237 retcode = ldap_parse_result(ld, res, &ld->ld_errno, &ld->ld_matched, &ld->ld_error,
238 &ld->ld_referrals, &ld->ld_ret_ctrls, 1);
239 if (retcode == LDAP_SUCCESS)
240 retcode = ld->ld_errno;
241 #ifdef _REENTRANT
242 UNLOCK_LDAP(ld);
243 #endif
244 return (retcode);
245 }
246
247