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