]> git.sur5r.net Git - openldap/blob - libraries/libldap/add.c
Happy new year! (belated)
[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-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