1 /* add.c */ 2 /* $OpenLDAP: pkg/ldap/libraries/libldap/add.c,v 1.27.2.3 2008/02/11 23:26:41 kurt Exp $ */ 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 223