1 #pragma ident "%Z%%M% %I% %E% SMI"
2
3 /*
4 * The contents of this file are subject to the Netscape Public
5 * License Version 1.1 (the "License"); you may not use this file
6 * except in compliance with the License. You may obtain a copy of
7 * the License at http://www.mozilla.org/NPL/
8 *
9 * Software distributed under the License is distributed on an "AS
10 * IS" basis, WITHOUT WARRANTY OF ANY KIND, either express or
11 * implied. See the License for the specific language governing
12 * rights and limitations under the License.
13 *
14 * The Original Code is Mozilla Communicator client code, released
15 * March 31, 1998.
16 *
17 * The Initial Developer of the Original Code is Netscape
18 * Communications Corporation. Portions created by Netscape are
19 * Copyright (C) 1998-1999 Netscape Communications Corporation. All
20 * Rights Reserved.
21 *
22 * Contributor(s):
23 */
24 /*
25 * Copyright (c) 1990 Regents of the University of Michigan.
26 * All rights reserved.
27 */
28 /*
29 * add.c
30 */
31
32 #if 0
33 #ifndef lint
34 static char copyright[] = "@(#) Copyright (c) 1990 Regents of the University of Michigan.\nAll rights reserved.\n";
35 #endif
36 #endif
37
38 #include "ldap-int.h"
39
40 /*
41 * ldap_add - initiate an ldap add operation. Parameters:
42 *
43 * ld LDAP descriptor
44 * dn DN of the entry to add
45 * mods List of attributes for the entry. This is a null-
46 * terminated array of pointers to LDAPMod structures.
47 * only the type and values in the structures need be
48 * filled in.
49 *
50 * Example:
51 * LDAPMod *attrs[] = {
52 * { 0, "cn", { "babs jensen", "babs", 0 } },
53 * { 0, "sn", { "jensen", 0 } },
54 * { 0, "objectClass", { "person", 0 } },
55 * 0
56 * }
57 * msgid = ldap_add( ld, dn, attrs );
58 */
59 int
60 LDAP_CALL
ldap_add(LDAP * ld,const char * dn,LDAPMod ** attrs)61 ldap_add( LDAP *ld, const char *dn, LDAPMod **attrs )
62 {
63 int msgid;
64
65 LDAPDebug( LDAP_DEBUG_TRACE, "ldap_add\n", 0, 0, 0 );
66
67 if ( ldap_add_ext( ld, dn, attrs, NULL, NULL, &msgid )
68 == LDAP_SUCCESS ) {
69 return( msgid );
70 } else {
71 return( -1 ); /* error is in ld handle */
72 }
73 }
74
75
76 /*
77 * LDAPv3 extended add.
78 * Returns an LDAP error code.
79 */
80 int
81 LDAP_CALL
ldap_add_ext(LDAP * ld,const char * dn,LDAPMod ** attrs,LDAPControl ** serverctrls,LDAPControl ** clientctrls,int * msgidp)82 ldap_add_ext( LDAP *ld, const char *dn, LDAPMod **attrs,
83 LDAPControl **serverctrls, LDAPControl **clientctrls, int *msgidp )
84 {
85 BerElement *ber;
86 int i, rc, lderr;
87
88 /*
89 * An add request looks like this:
90 * AddRequest ::= SEQUENCE {
91 * entry DistinguishedName,
92 * attrs SEQUENCE OF SEQUENCE {
93 * type AttributeType,
94 * values SET OF AttributeValue
95 * }
96 * }
97 */
98
99 LDAPDebug( LDAP_DEBUG_TRACE, "ldap_add_ext\n", 0, 0, 0 );
100
101 if ( !NSLDAPI_VALID_LDAP_POINTER( ld )) {
102 return( LDAP_PARAM_ERROR );
103 }
104
105 if ( !NSLDAPI_VALID_LDAPMESSAGE_POINTER( msgidp ))
106 {
107 LDAP_SET_LDERRNO( ld, LDAP_PARAM_ERROR, NULL, NULL );
108 return( LDAP_PARAM_ERROR );
109 }
110 if ( !NSLDAPI_VALID_NONEMPTY_LDAPMOD_ARRAY( attrs )
111 || msgidp == NULL ) {
112 lderr = LDAP_PARAM_ERROR;
113 LDAP_SET_LDERRNO( ld, lderr, NULL, NULL );
114 return( lderr );
115 }
116
117 if ( dn == NULL ) {
118 dn = "";
119 }
120
121 LDAP_MUTEX_LOCK( ld, LDAP_MSGID_LOCK );
122 *msgidp = ++ld->ld_msgid;
123 LDAP_MUTEX_UNLOCK( ld, LDAP_MSGID_LOCK );
124
125 /* see if we should add to the cache */
126 if ( ld->ld_cache_on && ld->ld_cache_add != NULL ) {
127 LDAP_MUTEX_LOCK( ld, LDAP_CACHE_LOCK );
128 if ( (rc = (ld->ld_cache_add)( ld, *msgidp, LDAP_REQ_ADD, dn,
129 attrs )) != 0 ) {
130 *msgidp = rc;
131 LDAP_MUTEX_UNLOCK( ld, LDAP_CACHE_LOCK );
132 return( LDAP_SUCCESS );
133 }
134 LDAP_MUTEX_UNLOCK( ld, LDAP_CACHE_LOCK );
135 }
136
137 /* create a message to send */
138 if (( lderr = nsldapi_alloc_ber_with_options( ld, &ber ))
139 != LDAP_SUCCESS ) {
140 return( lderr );
141 }
142
143 if ( ber_printf( ber, "{it{s{", *msgidp, LDAP_REQ_ADD, dn )
144 == -1 ) {
145 lderr = LDAP_ENCODING_ERROR;
146 LDAP_SET_LDERRNO( ld, lderr, NULL, NULL );
147 ber_free( ber, 1 );
148 return( lderr );
149 }
150
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]}", attrs[i]->mod_type,
155 attrs[i]->mod_bvalues );
156 } else {
157 rc = ber_printf( ber, "{s[v]}", attrs[i]->mod_type,
158 attrs[i]->mod_values );
159 }
160 if ( rc == -1 ) {
161 lderr = LDAP_ENCODING_ERROR;
162 LDAP_SET_LDERRNO( ld, lderr, NULL, NULL );
163 ber_free( ber, 1 );
164 return( lderr );
165 }
166 }
167
168 if ( ber_printf( ber, "}}" ) == -1 ) {
169 lderr = LDAP_ENCODING_ERROR;
170 LDAP_SET_LDERRNO( ld, lderr, NULL, NULL );
171 ber_free( ber, 1 );
172 return( lderr );
173 }
174
175 if (( lderr = nsldapi_put_controls( ld, serverctrls, 1, ber ))
176 != LDAP_SUCCESS ) {
177 ber_free( ber, 1 );
178 return( lderr );
179 }
180
181 /* send the message */
182 rc = nsldapi_send_initial_request( ld, *msgidp, LDAP_REQ_ADD,
183 (char *) dn, ber );
184 *msgidp = rc;
185 return( rc < 0 ? LDAP_GET_LDERRNO( ld, NULL, NULL ) : LDAP_SUCCESS );
186 }
187
188 int
189 LDAP_CALL
ldap_add_s(LDAP * ld,const char * dn,LDAPMod ** attrs)190 ldap_add_s( LDAP *ld, const char *dn, LDAPMod **attrs )
191 {
192 return( ldap_add_ext_s( ld, dn, attrs, NULL, NULL ));
193 }
194
195 int LDAP_CALL
ldap_add_ext_s(LDAP * ld,const char * dn,LDAPMod ** attrs,LDAPControl ** serverctrls,LDAPControl ** clientctrls)196 ldap_add_ext_s( LDAP *ld, const char *dn, LDAPMod **attrs,
197 LDAPControl **serverctrls, LDAPControl **clientctrls )
198 {
199 int err, msgid;
200 LDAPMessage *res;
201
202 if (( err = ldap_add_ext( ld, dn, attrs, serverctrls, clientctrls,
203 &msgid )) != LDAP_SUCCESS ) {
204 return( err );
205 }
206
207 if ( ldap_result( ld, msgid, 1, (struct timeval *)NULL, &res ) == -1 ) {
208 return( LDAP_GET_LDERRNO( ld, NULL, NULL ) );
209 }
210
211 return( ldap_result2error( ld, res, 1 ) );
212 }
213