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