xref: /onnv-gate/usr/src/lib/libldap4/common/modify.c (revision 3857:21b9b714e4ab)
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