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