]> git.sur5r.net Git - openldap/blob - libraries/libldap/add.c
afe4d873b066d831cfc36142dcf226742bba420c
[openldap] / libraries / libldap / add.c
1 /* add.c */
2 /* $OpenLDAP$ */
3 /* This work is part of OpenLDAP Software <http://www.openldap.org/>.
4  *
5  * Copyright 1998-2015 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 BerElement *
89 ldap_build_add_req(
90         LDAP *ld,
91         const char *dn,
92         LDAPMod **attrs,
93         LDAPControl **sctrls,
94         LDAPControl **cctrls,
95         ber_int_t       *msgidp )
96 {
97         BerElement *ber;
98         int i, rc;
99
100         /* create a message to send */
101         if ( (ber = ldap_alloc_ber_with_options( ld )) == NULL ) {
102                 return( NULL );
103         }
104
105         LDAP_NEXT_MSGID(ld, *msgidp);
106         rc = ber_printf( ber, "{it{s{", /* '}}}' */
107                 *msgidp, LDAP_REQ_ADD, dn );
108
109         if ( rc == -1 ) {
110                 ld->ld_errno = LDAP_ENCODING_ERROR;
111                 ber_free( ber, 1 );
112                 return( NULL );
113         }
114
115         /* allow attrs to be NULL ("touch"; should fail...) */
116         if ( attrs ) {
117                 /* for each attribute in the entry... */
118                 for ( i = 0; attrs[i] != NULL; i++ ) {
119                         if ( ( attrs[i]->mod_op & LDAP_MOD_BVALUES) != 0 ) {
120                                 int j;
121
122                                 if ( attrs[i]->mod_bvalues == NULL ) {
123                                         ld->ld_errno = LDAP_PARAM_ERROR;
124                                         ber_free( ber, 1 );
125                                         return( NULL );
126                                 }
127
128                                 for ( j = 0; attrs[i]->mod_bvalues[ j ] != NULL; j++ ) {
129                                         if ( attrs[i]->mod_bvalues[ j ]->bv_val == NULL ) {
130                                                 ld->ld_errno = LDAP_PARAM_ERROR;
131                                                 ber_free( ber, 1 );
132                                                 return( NULL );
133                                         }
134                                 }
135
136                                 rc = ber_printf( ber, "{s[V]N}", attrs[i]->mod_type,
137                                     attrs[i]->mod_bvalues );
138
139                         } else {
140                                 if ( attrs[i]->mod_values == NULL ) {
141                                         ld->ld_errno = LDAP_PARAM_ERROR;
142                                         ber_free( ber, 1 );
143                                         return( NULL );
144                                 }
145
146                                 rc = ber_printf( ber, "{s[v]N}", attrs[i]->mod_type,
147                                     attrs[i]->mod_values );
148                         }
149                         if ( rc == -1 ) {
150                                 ld->ld_errno = LDAP_ENCODING_ERROR;
151                                 ber_free( ber, 1 );
152                                 return( NULL );
153                         }
154                 }
155         }
156
157         if ( ber_printf( ber, /*{{*/ "N}N}" ) == -1 ) {
158                 ld->ld_errno = LDAP_ENCODING_ERROR;
159                 ber_free( ber, 1 );
160                 return( NULL );
161         }
162
163         /* Put Server Controls */
164         if( ldap_int_put_controls( ld, sctrls, ber ) != LDAP_SUCCESS ) {
165                 ber_free( ber, 1 );
166                 return( NULL );
167         }
168
169         if ( ber_printf( ber, /*{*/ "N}" ) == -1 ) {
170                 ld->ld_errno = LDAP_ENCODING_ERROR;
171                 ber_free( ber, 1 );
172                 return( NULL );
173         }
174
175         return( ber );
176 }
177
178 /*
179  * ldap_add_ext - initiate an ldap extended add operation.  Parameters:
180  *
181  *      ld              LDAP descriptor
182  *      dn              DN of the entry to add
183  *      mods            List of attributes for the entry.  This is a null-
184  *                      terminated array of pointers to LDAPMod structures.
185  *                      only the type and values in the structures need be
186  *                      filled in.
187  *      sctrl   Server Controls
188  *      cctrl   Client Controls
189  *      msgidp  Message ID pointer
190  *
191  * Example:
192  *      LDAPMod *attrs[] = {
193  *                      { 0, "cn", { "babs jensen", "babs", 0 } },
194  *                      { 0, "sn", { "jensen", 0 } },
195  *                      { 0, "objectClass", { "person", 0 } },
196  *                      0
197  *              }
198  *      rc = ldap_add_ext( ld, dn, attrs, NULL, NULL, &msgid );
199  */
200 int
201 ldap_add_ext(
202         LDAP *ld,
203         LDAP_CONST char *dn,
204         LDAPMod **attrs,
205         LDAPControl **sctrls,
206         LDAPControl **cctrls,
207         int     *msgidp )
208 {
209         BerElement      *ber;
210         int             i, rc;
211         ber_int_t       id;
212
213         Debug( LDAP_DEBUG_TRACE, "ldap_add_ext\n", 0, 0, 0 );
214         assert( ld != NULL );
215         assert( LDAP_VALID( ld ) );
216         assert( dn != NULL );
217         assert( msgidp != NULL );
218
219         /* check client controls */
220         rc = ldap_int_client_controls( ld, cctrls );
221         if( rc != LDAP_SUCCESS ) return rc;
222
223         ber = ldap_build_add_req( ld, dn, attrs, sctrls, cctrls, &id );
224         if( !ber )
225                 return ld->ld_errno;
226
227         /* send the message */
228         *msgidp = ldap_send_initial_request( ld, LDAP_REQ_ADD, dn, ber, id );
229
230         if(*msgidp < 0)
231                 return ld->ld_errno;
232
233         return LDAP_SUCCESS;
234 }
235
236 int
237 ldap_add_ext_s(
238         LDAP *ld,
239         LDAP_CONST char *dn,
240         LDAPMod **attrs,
241         LDAPControl **sctrls,
242         LDAPControl **cctrls )
243 {
244         int             msgid, rc;
245         LDAPMessage     *res;
246
247         rc = ldap_add_ext( ld, dn, attrs, sctrls, cctrls, &msgid );
248
249         if ( rc != LDAP_SUCCESS )
250                 return( rc );
251
252         if ( ldap_result( ld, msgid, LDAP_MSG_ALL, (struct timeval *) NULL, &res ) == -1 || !res )
253                 return( ld->ld_errno );
254
255         return( ldap_result2error( ld, res, 1 ) );
256 }
257
258 int
259 ldap_add_s( LDAP *ld, LDAP_CONST char *dn, LDAPMod **attrs )
260 {
261         return ldap_add_ext_s( ld, dn, attrs, NULL, NULL );
262 }
263