1 /* $NetBSD: add.c,v 1.1.1.2 2010/03/08 02:14:20 lukem Exp $ */ 2 3 /* add.c */ 4 /* OpenLDAP: pkg/ldap/libraries/libldap/add.c,v 1.27.2.5 2009/01/22 00:00:54 kurt Exp */ 5 /* This work is part of OpenLDAP Software <http://www.openldap.org/>. 6 * 7 * Copyright 1998-2009 The OpenLDAP Foundation. 8 * All rights reserved. 9 * 10 * Redistribution and use in source and binary forms, with or without 11 * modification, are permitted only as authorized by the OpenLDAP 12 * Public License. 13 * 14 * A copy of this license is available in the file LICENSE in the 15 * top-level directory of the distribution or, alternatively, at 16 * <http://www.OpenLDAP.org/license.html>. 17 */ 18 /* Portions Copyright (c) 1990 Regents of the University of Michigan. 19 * All rights reserved. 20 */ 21 22 #include "portable.h" 23 24 #include <stdio.h> 25 26 #include <ac/socket.h> 27 #include <ac/string.h> 28 #include <ac/time.h> 29 30 #include "ldap-int.h" 31 32 /* An LDAP Add Request/Response looks like this: 33 * AddRequest ::= [APPLICATION 8] SEQUENCE { 34 * entry LDAPDN, 35 * attributes AttributeList } 36 * 37 * AttributeList ::= SEQUENCE OF attribute Attribute 38 * 39 * Attribute ::= PartialAttribute(WITH COMPONENTS { 40 * ..., 41 * vals (SIZE(1..MAX))}) 42 * 43 * PartialAttribute ::= SEQUENCE { 44 * type AttributeDescription, 45 * vals SET OF value AttributeValue } 46 * 47 * AttributeDescription ::= LDAPString 48 * -- Constrained to <attributedescription> [RFC4512] 49 * 50 * AttributeValue ::= OCTET STRING 51 * 52 * AddResponse ::= [APPLICATION 9] LDAPResult 53 * (Source: RFC 4511) 54 */ 55 56 /* 57 * ldap_add - initiate an ldap add operation. Parameters: 58 * 59 * ld LDAP descriptor 60 * dn DN of the entry to add 61 * mods List of attributes for the entry. This is a null- 62 * terminated array of pointers to LDAPMod structures. 63 * only the type and values in the structures need be 64 * filled in. 65 * 66 * Example: 67 * LDAPMod *attrs[] = { 68 * { 0, "cn", { "babs jensen", "babs", 0 } }, 69 * { 0, "sn", { "jensen", 0 } }, 70 * { 0, "objectClass", { "person", 0 } }, 71 * 0 72 * } 73 * msgid = ldap_add( ld, dn, attrs ); 74 */ 75 int 76 ldap_add( LDAP *ld, LDAP_CONST char *dn, LDAPMod **attrs ) 77 { 78 int rc; 79 int msgid; 80 81 rc = ldap_add_ext( ld, dn, attrs, NULL, NULL, &msgid ); 82 83 if ( rc != LDAP_SUCCESS ) 84 return -1; 85 86 return msgid; 87 } 88 89 90 /* 91 * ldap_add_ext - initiate an ldap extended add operation. Parameters: 92 * 93 * ld LDAP descriptor 94 * dn DN of the entry to add 95 * mods List of attributes for the entry. This is a null- 96 * terminated array of pointers to LDAPMod structures. 97 * only the type and values in the structures need be 98 * filled in. 99 * sctrl Server Controls 100 * cctrl Client Controls 101 * msgidp Message ID pointer 102 * 103 * Example: 104 * LDAPMod *attrs[] = { 105 * { 0, "cn", { "babs jensen", "babs", 0 } }, 106 * { 0, "sn", { "jensen", 0 } }, 107 * { 0, "objectClass", { "person", 0 } }, 108 * 0 109 * } 110 * rc = ldap_add_ext( ld, dn, attrs, NULL, NULL, &msgid ); 111 */ 112 int 113 ldap_add_ext( 114 LDAP *ld, 115 LDAP_CONST char *dn, 116 LDAPMod **attrs, 117 LDAPControl **sctrls, 118 LDAPControl **cctrls, 119 int *msgidp ) 120 { 121 BerElement *ber; 122 int i, rc; 123 ber_int_t id; 124 125 Debug( LDAP_DEBUG_TRACE, "ldap_add_ext\n", 0, 0, 0 ); 126 assert( ld != NULL ); 127 assert( LDAP_VALID( ld ) ); 128 assert( dn != NULL ); 129 assert( msgidp != NULL ); 130 131 /* check client controls */ 132 rc = ldap_int_client_controls( ld, cctrls ); 133 if( rc != LDAP_SUCCESS ) return rc; 134 135 /* create a message to send */ 136 if ( (ber = ldap_alloc_ber_with_options( ld )) == NULL ) { 137 ld->ld_errno = LDAP_NO_MEMORY; 138 return ld->ld_errno; 139 } 140 141 LDAP_NEXT_MSGID(ld, id); 142 rc = ber_printf( ber, "{it{s{", /* '}}}' */ 143 id, LDAP_REQ_ADD, dn ); 144 145 if ( rc == -1 ) { 146 ld->ld_errno = LDAP_ENCODING_ERROR; 147 ber_free( ber, 1 ); 148 return ld->ld_errno; 149 } 150 151 /* allow attrs to be NULL ("touch"; should fail...) */ 152 if ( attrs ) { 153 /* for each attribute in the entry... */ 154 for ( i = 0; attrs[i] != NULL; i++ ) { 155 if ( ( attrs[i]->mod_op & LDAP_MOD_BVALUES) != 0 ) { 156 int j; 157 158 if ( attrs[i]->mod_bvalues == NULL ) { 159 ld->ld_errno = LDAP_PARAM_ERROR; 160 ber_free( ber, 1 ); 161 return ld->ld_errno; 162 } 163 164 for ( j = 0; attrs[i]->mod_bvalues[ j ] != NULL; j++ ) { 165 if ( attrs[i]->mod_bvalues[ j ]->bv_val == NULL ) { 166 ld->ld_errno = LDAP_PARAM_ERROR; 167 ber_free( ber, 1 ); 168 return ld->ld_errno; 169 } 170 } 171 172 rc = ber_printf( ber, "{s[V]N}", attrs[i]->mod_type, 173 attrs[i]->mod_bvalues ); 174 175 } else { 176 if ( attrs[i]->mod_values == NULL ) { 177 ld->ld_errno = LDAP_PARAM_ERROR; 178 ber_free( ber, 1 ); 179 return ld->ld_errno; 180 } 181 182 rc = ber_printf( ber, "{s[v]N}", attrs[i]->mod_type, 183 attrs[i]->mod_values ); 184 } 185 if ( rc == -1 ) { 186 ld->ld_errno = LDAP_ENCODING_ERROR; 187 ber_free( ber, 1 ); 188 return ld->ld_errno; 189 } 190 } 191 } 192 193 if ( ber_printf( ber, /*{{*/ "N}N}" ) == -1 ) { 194 ld->ld_errno = LDAP_ENCODING_ERROR; 195 ber_free( ber, 1 ); 196 return ld->ld_errno; 197 } 198 199 /* Put Server Controls */ 200 if( ldap_int_put_controls( ld, sctrls, ber ) != LDAP_SUCCESS ) { 201 ber_free( ber, 1 ); 202 return ld->ld_errno; 203 } 204 205 if ( ber_printf( ber, /*{*/ "N}" ) == -1 ) { 206 ld->ld_errno = LDAP_ENCODING_ERROR; 207 ber_free( ber, 1 ); 208 return ld->ld_errno; 209 } 210 211 /* send the message */ 212 *msgidp = ldap_send_initial_request( ld, LDAP_REQ_ADD, dn, ber, id ); 213 214 if(*msgidp < 0) 215 return ld->ld_errno; 216 217 return LDAP_SUCCESS; 218 } 219 220 int 221 ldap_add_ext_s( 222 LDAP *ld, 223 LDAP_CONST char *dn, 224 LDAPMod **attrs, 225 LDAPControl **sctrls, 226 LDAPControl **cctrls ) 227 { 228 int msgid, rc; 229 LDAPMessage *res; 230 231 rc = ldap_add_ext( ld, dn, attrs, sctrls, cctrls, &msgid ); 232 233 if ( rc != LDAP_SUCCESS ) 234 return( rc ); 235 236 if ( ldap_result( ld, msgid, LDAP_MSG_ALL, (struct timeval *) NULL, &res ) == -1 || !res ) 237 return( ld->ld_errno ); 238 239 return( ldap_result2error( ld, res, 1 ) ); 240 } 241 242 int 243 ldap_add_s( LDAP *ld, LDAP_CONST char *dn, LDAPMod **attrs ) 244 { 245 return ldap_add_ext_s( ld, dn, attrs, NULL, NULL ); 246 } 247 248