1 #pragma ident "%Z%%M% %I% %E% SMI"
2
3 /*
4 * The contents of this file are subject to the Netscape Public
5 * License Version 1.1 (the "License"); you may not use this file
6 * except in compliance with the License. You may obtain a copy of
7 * the License at http://www.mozilla.org/NPL/
8 *
9 * Software distributed under the License is distributed on an "AS
10 * IS" basis, WITHOUT WARRANTY OF ANY KIND, either express or
11 * implied. See the License for the specific language governing
12 * rights and limitations under the License.
13 *
14 * The Original Code is Mozilla Communicator client code, released
15 * March 31, 1998.
16 *
17 * The Initial Developer of the Original Code is Netscape
18 * Communications Corporation. Portions created by Netscape are
19 * Copyright (C) 1998-1999 Netscape Communications Corporation. All
20 * Rights Reserved.
21 *
22 * Contributor(s):
23 */
24 /*
25 * Copyright (c) 1990 Regents of the University of Michigan.
26 * All rights reserved.
27 */
28 /*
29 * modify.c
30 */
31
32 #if 0
33 #ifndef lint
34 static char copyright[] = "@(#) Copyright (c) 1990 Regents of the University of Michigan.\nAll rights reserved.\n";
35 #endif
36 #endif
37
38 #include "ldap-int.h"
39
40 /*
41 * ldap_modify - initiate an ldap modify operation. Parameters:
42 *
43 * ld LDAP descriptor
44 * dn DN of the object to modify
45 * mods List of modifications to make. This is null-terminated
46 * array of struct ldapmod's, specifying the modifications
47 * to perform.
48 *
49 * Example:
50 * LDAPMod *mods[] = {
51 * { LDAP_MOD_ADD, "cn", { "babs jensen", "babs", 0 } },
52 * { LDAP_MOD_REPLACE, "sn", { "jensen", 0 } },
53 * 0
54 * }
55 * msgid = ldap_modify( ld, dn, mods );
56 */
57 int
58 LDAP_CALL
ldap_modify(LDAP * ld,const char * dn,LDAPMod ** mods)59 ldap_modify( LDAP *ld, const char *dn, LDAPMod **mods )
60 {
61 int msgid;
62
63 LDAPDebug( LDAP_DEBUG_TRACE, "ldap_modify\n", 0, 0, 0 );
64
65 if ( ldap_modify_ext( ld, dn, mods, NULL, NULL, &msgid )
66 == LDAP_SUCCESS ) {
67 return( msgid );
68 } else {
69 return( -1 ); /* error is in ld handle */
70 }
71 }
72
73 int
74 LDAP_CALL
ldap_modify_ext(LDAP * ld,const char * dn,LDAPMod ** mods,LDAPControl ** serverctrls,LDAPControl ** clientctrls,int * msgidp)75 ldap_modify_ext( LDAP *ld, const char *dn, LDAPMod **mods,
76 LDAPControl **serverctrls, LDAPControl **clientctrls, int *msgidp )
77 {
78 BerElement *ber;
79 int i, rc, lderr;
80
81 /*
82 * A modify request looks like this:
83 * ModifyRequet ::= SEQUENCE {
84 * object DistinguishedName,
85 * modifications SEQUENCE OF SEQUENCE {
86 * operation ENUMERATED {
87 * add (0),
88 * delete (1),
89 * replace (2)
90 * },
91 * modification SEQUENCE {
92 * type AttributeType,
93 * values SET OF AttributeValue
94 * }
95 * }
96 * }
97 */
98
99 LDAPDebug( LDAP_DEBUG_TRACE, "ldap_modify_ext\n", 0, 0, 0 );
100
101 if ( !NSLDAPI_VALID_LDAP_POINTER( ld )) {
102 return( LDAP_PARAM_ERROR );
103 }
104 if ( !NSLDAPI_VALID_LDAPMESSAGE_POINTER( msgidp ))
105 {
106 LDAP_SET_LDERRNO( ld, LDAP_PARAM_ERROR, NULL, NULL );
107 return( LDAP_PARAM_ERROR );
108 }
109
110 if ( !NSLDAPI_VALID_NONEMPTY_LDAPMOD_ARRAY( mods )) {
111 lderr = LDAP_PARAM_ERROR;
112 LDAP_SET_LDERRNO( ld, lderr, NULL, NULL );
113 return( lderr );
114 }
115 if ( dn == NULL ) {
116 dn = "";
117 }
118
119 LDAP_MUTEX_LOCK( ld, LDAP_MSGID_LOCK );
120 *msgidp = ++ld->ld_msgid;
121 LDAP_MUTEX_UNLOCK( ld, LDAP_MSGID_LOCK );
122
123 /* see if we should add to the cache */
124 if ( ld->ld_cache_on && ld->ld_cache_modify != NULL ) {
125 LDAP_MUTEX_LOCK( ld, LDAP_CACHE_LOCK );
126 if ( (rc = (ld->ld_cache_modify)( ld, *msgidp, LDAP_REQ_MODIFY,
127 dn, mods )) != 0 ) {
128 *msgidp = rc;
129 LDAP_MUTEX_UNLOCK( ld, LDAP_CACHE_LOCK );
130 return( LDAP_SUCCESS );
131 }
132 LDAP_MUTEX_UNLOCK( ld, LDAP_CACHE_LOCK );
133 }
134
135 /* create a message to send */
136 if (( lderr = nsldapi_alloc_ber_with_options( ld, &ber ))
137 != LDAP_SUCCESS ) {
138 return( lderr );
139 }
140
141 if ( ber_printf( ber, "{it{s{", *msgidp, LDAP_REQ_MODIFY, dn )
142 == -1 ) {
143 lderr = LDAP_ENCODING_ERROR;
144 LDAP_SET_LDERRNO( ld, lderr, NULL, NULL );
145 ber_free( ber, 1 );
146 return( lderr );
147 }
148
149 /* for each modification to be performed... */
150 for ( i = 0; mods[i] != NULL; i++ ) {
151 if (( mods[i]->mod_op & LDAP_MOD_BVALUES) != 0 ) {
152 rc = ber_printf( ber, "{e{s[V]}}",
153 mods[i]->mod_op & ~LDAP_MOD_BVALUES,
154 mods[i]->mod_type, mods[i]->mod_bvalues );
155 } else {
156 rc = ber_printf( ber, "{e{s[v]}}", mods[i]->mod_op,
157 mods[i]->mod_type, mods[i]->mod_values );
158 }
159
160 if ( rc == -1 ) {
161 lderr = LDAP_ENCODING_ERROR;
162 LDAP_SET_LDERRNO( ld, lderr, NULL, NULL );
163 ber_free( ber, 1 );
164 return( lderr );
165 }
166 }
167
168 if ( ber_printf( ber, "}}" ) == -1 ) {
169 lderr = LDAP_ENCODING_ERROR;
170 LDAP_SET_LDERRNO( ld, lderr, NULL, NULL );
171 ber_free( ber, 1 );
172 return( lderr );
173 }
174
175 if (( lderr = nsldapi_put_controls( ld, serverctrls, 1, ber ))
176 != LDAP_SUCCESS ) {
177 ber_free( ber, 1 );
178 return( lderr );
179 }
180
181 /* send the message */
182 rc = nsldapi_send_initial_request( ld, *msgidp, LDAP_REQ_MODIFY,
183 (char *)dn, ber );
184 *msgidp = rc;
185 return( rc < 0 ? LDAP_GET_LDERRNO( ld, NULL, NULL ) : LDAP_SUCCESS );
186 }
187
188 int
189 LDAP_CALL
ldap_modify_s(LDAP * ld,const char * dn,LDAPMod ** mods)190 ldap_modify_s( LDAP *ld, const char *dn, LDAPMod **mods )
191 {
192 return( ldap_modify_ext_s( ld, dn, mods, NULL, NULL ));
193 }
194
195 int
196 LDAP_CALL
ldap_modify_ext_s(LDAP * ld,const char * dn,LDAPMod ** mods,LDAPControl ** serverctrls,LDAPControl ** clientctrls)197 ldap_modify_ext_s( LDAP *ld, const char *dn, LDAPMod **mods,
198 LDAPControl **serverctrls, LDAPControl **clientctrls )
199 {
200 int msgid, err;
201 LDAPMessage *res;
202
203 if (( err = ldap_modify_ext( ld, dn, mods, serverctrls, clientctrls,
204 &msgid )) != LDAP_SUCCESS ) {
205 return( err );
206 }
207
208 if ( ldap_result( ld, msgid, 1, (struct timeval *)NULL, &res ) == -1 ) {
209 return( LDAP_GET_LDERRNO( ld, NULL, NULL ) );
210 }
211
212 return( ldap_result2error( ld, res, 1 ) );
213 }
214