]> git.sur5r.net Git - openldap/blob - libraries/libldap/add.c
03b334b31a3fa84d3ed02935bf2e408d734803b1
[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 /*
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                                 int j;
155
156                                 if ( attrs[i]->mod_bvalues == NULL ) {
157                                         ld->ld_errno = LDAP_PARAM_ERROR;
158                                         ber_free( ber, 1 );
159                                         return ld->ld_errno;
160                                 }
161
162                                 for ( j = 0; attrs[i]->mod_bvalues[ j ] != NULL; j++ ) {
163                                         if ( attrs[i]->mod_bvalues[ j ]->bv_val == NULL ) {
164                                                 ld->ld_errno = LDAP_PARAM_ERROR;
165                                                 ber_free( ber, 1 );
166                                                 return ld->ld_errno;
167                                         }
168                                 }
169
170                                 rc = ber_printf( ber, "{s[V]N}", attrs[i]->mod_type,
171                                     attrs[i]->mod_bvalues );
172
173                         } else {
174                                 if ( attrs[i]->mod_values == NULL ) {
175                                         ld->ld_errno = LDAP_PARAM_ERROR;
176                                         ber_free( ber, 1 );
177                                         return ld->ld_errno;
178                                 }
179
180                                 rc = ber_printf( ber, "{s[v]N}", attrs[i]->mod_type,
181                                     attrs[i]->mod_values );
182                         }
183                         if ( rc == -1 ) {
184                                 ld->ld_errno = LDAP_ENCODING_ERROR;
185                                 ber_free( ber, 1 );
186                                 return ld->ld_errno;
187                         }
188                 }
189         }
190
191         if ( ber_printf( ber, /*{{*/ "N}N}" ) == -1 ) {
192                 ld->ld_errno = LDAP_ENCODING_ERROR;
193                 ber_free( ber, 1 );
194                 return ld->ld_errno;
195         }
196
197         /* Put Server Controls */
198         if( ldap_int_put_controls( ld, sctrls, ber ) != LDAP_SUCCESS ) {
199                 ber_free( ber, 1 );
200                 return ld->ld_errno;
201         }
202
203         if ( ber_printf( ber, /*{*/ "N}" ) == -1 ) {
204                 ld->ld_errno = LDAP_ENCODING_ERROR;
205                 ber_free( ber, 1 );
206                 return ld->ld_errno;
207         }
208
209         /* send the message */
210         *msgidp = ldap_send_initial_request( ld, LDAP_REQ_ADD, dn, ber, id );
211
212         if(*msgidp < 0)
213                 return ld->ld_errno;
214
215         return LDAP_SUCCESS;
216 }
217
218 int
219 ldap_add_ext_s(
220         LDAP *ld,
221         LDAP_CONST char *dn,
222         LDAPMod **attrs,
223         LDAPControl **sctrls,
224         LDAPControl **cctrls )
225 {
226         int             msgid, rc;
227         LDAPMessage     *res;
228
229         rc = ldap_add_ext( ld, dn, attrs, sctrls, cctrls, &msgid );
230
231         if ( rc != LDAP_SUCCESS )
232                 return( rc );
233
234         if ( ldap_result( ld, msgid, LDAP_MSG_ALL, (struct timeval *) NULL, &res ) == -1 || !res )
235                 return( ld->ld_errno );
236
237         return( ldap_result2error( ld, res, 1 ) );
238 }
239
240 int
241 ldap_add_s( LDAP *ld, LDAP_CONST char *dn, LDAPMod **attrs )
242 {
243         return ldap_add_ext_s( ld, dn, attrs, NULL, NULL );
244 }
245