xref: /netbsd-src/external/bsd/openldap/dist/libraries/libldap/add.c (revision 404fbe5fb94ca1e054339640cabb2801ce52dd30)
1 /* add.c */
2 /* $OpenLDAP: pkg/ldap/libraries/libldap/add.c,v 1.27.2.3 2008/02/11 23:26:41 kurt Exp $ */
3 /* This work is part of OpenLDAP Software <http://www.openldap.org/>.
4  *
5  * Copyright 1998-2008 The OpenLDAP Foundation.
6  * All rights reserved.
7  *
8  * Redistribution and use in source and binary forms, with or without
9  * modification, are permitted only as authorized by the OpenLDAP
10  * Public License.
11  *
12  * A copy of this license is available in the file LICENSE in the
13  * top-level directory of the distribution or, alternatively, at
14  * <http://www.OpenLDAP.org/license.html>.
15  */
16 /* Portions Copyright (c) 1990 Regents of the University of Michigan.
17  * All rights reserved.
18  */
19 
20 #include "portable.h"
21 
22 #include <stdio.h>
23 
24 #include <ac/socket.h>
25 #include <ac/string.h>
26 #include <ac/time.h>
27 
28 #include "ldap-int.h"
29 
30 /* An LDAP Add Request/Response looks like this:
31  *        AddRequest ::= [APPLICATION 8] SEQUENCE {
32  *            entry           LDAPDN,
33  *            attributes      AttributeList }
34  *
35  *        AttributeList ::= SEQUENCE OF attribute Attribute
36  *
37  *        Attribute ::= PartialAttribute(WITH COMPONENTS {
38  *             ...,
39  *             vals (SIZE(1..MAX))})
40  *
41  *        PartialAttribute ::= SEQUENCE {
42  *             type       AttributeDescription,
43  *             vals       SET OF value AttributeValue }
44  *
45  *        AttributeDescription ::= LDAPString
46  *             -- Constrained to <attributedescription> [RFC4512]
47  *
48  *        AttributeValue ::= OCTET STRING
49  *
50  *        AddResponse ::= [APPLICATION 9] LDAPResult
51  * (Source: RFC 4511)
52  */
53 
54 /*
55  * ldap_add - initiate an ldap add operation.  Parameters:
56  *
57  *	ld		LDAP descriptor
58  *	dn		DN of the entry to add
59  *	mods		List of attributes for the entry.  This is a null-
60  *			terminated array of pointers to LDAPMod structures.
61  *			only the type and values in the structures need be
62  *			filled in.
63  *
64  * Example:
65  *	LDAPMod	*attrs[] = {
66  *			{ 0, "cn", { "babs jensen", "babs", 0 } },
67  *			{ 0, "sn", { "jensen", 0 } },
68  *			{ 0, "objectClass", { "person", 0 } },
69  *			0
70  *		}
71  *	msgid = ldap_add( ld, dn, attrs );
72  */
73 int
74 ldap_add( LDAP *ld, LDAP_CONST char *dn, LDAPMod **attrs )
75 {
76 	int rc;
77 	int msgid;
78 
79 	rc = ldap_add_ext( ld, dn, attrs, NULL, NULL, &msgid );
80 
81 	if ( rc != LDAP_SUCCESS )
82 		return -1;
83 
84 	return msgid;
85 }
86 
87 
88 /*
89  * ldap_add_ext - initiate an ldap extended add operation.  Parameters:
90  *
91  *	ld		LDAP descriptor
92  *	dn		DN of the entry to add
93  *	mods		List of attributes for the entry.  This is a null-
94  *			terminated array of pointers to LDAPMod structures.
95  *			only the type and values in the structures need be
96  *			filled in.
97  *	sctrl	Server Controls
98  *	cctrl	Client Controls
99  *	msgidp	Message ID pointer
100  *
101  * Example:
102  *	LDAPMod	*attrs[] = {
103  *			{ 0, "cn", { "babs jensen", "babs", 0 } },
104  *			{ 0, "sn", { "jensen", 0 } },
105  *			{ 0, "objectClass", { "person", 0 } },
106  *			0
107  *		}
108  *	rc = ldap_add_ext( ld, dn, attrs, NULL, NULL, &msgid );
109  */
110 int
111 ldap_add_ext(
112 	LDAP *ld,
113 	LDAP_CONST char *dn,
114 	LDAPMod **attrs,
115 	LDAPControl **sctrls,
116 	LDAPControl **cctrls,
117 	int	*msgidp )
118 {
119 	BerElement	*ber;
120 	int		i, rc;
121 	ber_int_t	id;
122 
123 	Debug( LDAP_DEBUG_TRACE, "ldap_add_ext\n", 0, 0, 0 );
124 	assert( ld != NULL );
125 	assert( LDAP_VALID( ld ) );
126 	assert( dn != NULL );
127 	assert( msgidp != NULL );
128 
129 	/* check client controls */
130 	rc = ldap_int_client_controls( ld, cctrls );
131 	if( rc != LDAP_SUCCESS ) return rc;
132 
133 	/* create a message to send */
134 	if ( (ber = ldap_alloc_ber_with_options( ld )) == NULL ) {
135 		ld->ld_errno = LDAP_NO_MEMORY;
136 		return ld->ld_errno;
137 	}
138 
139 	LDAP_NEXT_MSGID(ld, id);
140 	rc = ber_printf( ber, "{it{s{", /* '}}}' */
141 		id, LDAP_REQ_ADD, dn );
142 
143 	if ( rc == -1 ) {
144 		ld->ld_errno = LDAP_ENCODING_ERROR;
145 		ber_free( ber, 1 );
146 		return ld->ld_errno;
147 	}
148 
149 	/* allow attrs to be NULL ("touch"; should fail...) */
150 	if ( attrs ) {
151 		/* for each attribute in the entry... */
152 		for ( i = 0; attrs[i] != NULL; i++ ) {
153 			if ( ( attrs[i]->mod_op & LDAP_MOD_BVALUES) != 0 ) {
154 				rc = ber_printf( ber, "{s[V]N}", attrs[i]->mod_type,
155 				    attrs[i]->mod_bvalues );
156 			} else {
157 				rc = ber_printf( ber, "{s[v]N}", attrs[i]->mod_type,
158 				    attrs[i]->mod_values );
159 			}
160 			if ( rc == -1 ) {
161 				ld->ld_errno = LDAP_ENCODING_ERROR;
162 				ber_free( ber, 1 );
163 				return ld->ld_errno;
164 			}
165 		}
166 	}
167 
168 	if ( ber_printf( ber, /*{{*/ "N}N}" ) == -1 ) {
169 		ld->ld_errno = LDAP_ENCODING_ERROR;
170 		ber_free( ber, 1 );
171 		return ld->ld_errno;
172 	}
173 
174 	/* Put Server Controls */
175 	if( ldap_int_put_controls( ld, sctrls, ber ) != LDAP_SUCCESS ) {
176 		ber_free( ber, 1 );
177 		return ld->ld_errno;
178 	}
179 
180 	if ( ber_printf( ber, /*{*/ "N}" ) == -1 ) {
181 		ld->ld_errno = LDAP_ENCODING_ERROR;
182 		ber_free( ber, 1 );
183 		return ld->ld_errno;
184 	}
185 
186 	/* send the message */
187 	*msgidp = ldap_send_initial_request( ld, LDAP_REQ_ADD, dn, ber, id );
188 
189 	if(*msgidp < 0)
190 		return ld->ld_errno;
191 
192 	return LDAP_SUCCESS;
193 }
194 
195 int
196 ldap_add_ext_s(
197 	LDAP *ld,
198 	LDAP_CONST char *dn,
199 	LDAPMod **attrs,
200 	LDAPControl **sctrls,
201 	LDAPControl **cctrls )
202 {
203 	int		msgid, rc;
204 	LDAPMessage	*res;
205 
206 	rc = ldap_add_ext( ld, dn, attrs, sctrls, cctrls, &msgid );
207 
208 	if ( rc != LDAP_SUCCESS )
209 		return( rc );
210 
211 	if ( ldap_result( ld, msgid, LDAP_MSG_ALL, (struct timeval *) NULL, &res ) == -1 || !res )
212 		return( ld->ld_errno );
213 
214 	return( ldap_result2error( ld, res, 1 ) );
215 }
216 
217 int
218 ldap_add_s( LDAP *ld, LDAP_CONST char *dn, LDAPMod **attrs )
219 {
220 	return ldap_add_ext_s( ld, dn, attrs, NULL, NULL );
221 }
222 
223