X-Git-Url: https://git.sur5r.net/?a=blobdiff_plain;f=libraries%2Flibldap%2Fadd.c;h=6c8da84602fb77fff67eb452b6be63bb41c14068;hb=b905811d3c800b6f4031d541e424e5de871aa0c7;hp=73e84964c1ae19c54f5354951fb387d3b0a4d916;hpb=2a869f5a99f537b246ba8640502e2a86117cb6e8;p=openldap diff --git a/libraries/libldap/add.c b/libraries/libldap/add.c index 73e84964c1..6c8da84602 100644 --- a/libraries/libldap/add.c +++ b/libraries/libldap/add.c @@ -1,28 +1,58 @@ -/* - * Copyright (c) 1990 Regents of the University of Michigan. - * All rights reserved. +/* add.c */ +/* $OpenLDAP$ */ +/* This work is part of OpenLDAP Software . + * + * Copyright 1998-2011 The OpenLDAP Foundation. + * All rights reserved. * - * add.c + * Redistribution and use in source and binary forms, with or without + * modification, are permitted only as authorized by the OpenLDAP + * Public License. + * + * A copy of this license is available in the file LICENSE in the + * top-level directory of the distribution or, alternatively, at + * . + */ +/* Portions Copyright (c) 1990 Regents of the University of Michigan. + * All rights reserved. */ #include "portable.h" -#ifndef lint -static char copyright[] = "@(#) Copyright (c) 1990 Regents of the University of Michigan.\nAll rights reserved.\n"; -#endif - #include #include #include #include -#include "lber.h" -#include "ldap.h" #include "ldap-int.h" +/* An LDAP Add Request/Response looks like this: + * AddRequest ::= [APPLICATION 8] SEQUENCE { + * entry LDAPDN, + * attributes AttributeList } + * + * AttributeList ::= SEQUENCE OF attribute Attribute + * + * Attribute ::= PartialAttribute(WITH COMPONENTS { + * ..., + * vals (SIZE(1..MAX))}) + * + * PartialAttribute ::= SEQUENCE { + * type AttributeDescription, + * vals SET OF value AttributeValue } + * + * AttributeDescription ::= LDAPString + * -- Constrained to [RFC4512] + * + * AttributeValue ::= OCTET STRING + * + * AddResponse ::= [APPLICATION 9] LDAPResult + * (Source: RFC 4511) + */ + /* - * ldap_add - initiate an ldap (and X.500) add operation. Parameters: + * ldap_add - initiate an ldap add operation. Parameters: * * ld LDAP descriptor * dn DN of the entry to add @@ -41,74 +71,175 @@ static char copyright[] = "@(#) Copyright (c) 1990 Regents of the University of * msgid = ldap_add( ld, dn, attrs ); */ int -ldap_add( LDAP *ld, char *dn, LDAPMod **attrs ) +ldap_add( LDAP *ld, LDAP_CONST char *dn, LDAPMod **attrs ) +{ + int rc; + int msgid; + + rc = ldap_add_ext( ld, dn, attrs, NULL, NULL, &msgid ); + + if ( rc != LDAP_SUCCESS ) + return -1; + + return msgid; +} + + +/* + * ldap_add_ext - initiate an ldap extended add operation. Parameters: + * + * ld LDAP descriptor + * dn DN of the entry to add + * mods List of attributes for the entry. This is a null- + * terminated array of pointers to LDAPMod structures. + * only the type and values in the structures need be + * filled in. + * sctrl Server Controls + * cctrl Client Controls + * msgidp Message ID pointer + * + * Example: + * LDAPMod *attrs[] = { + * { 0, "cn", { "babs jensen", "babs", 0 } }, + * { 0, "sn", { "jensen", 0 } }, + * { 0, "objectClass", { "person", 0 } }, + * 0 + * } + * rc = ldap_add_ext( ld, dn, attrs, NULL, NULL, &msgid ); + */ +int +ldap_add_ext( + LDAP *ld, + LDAP_CONST char *dn, + LDAPMod **attrs, + LDAPControl **sctrls, + LDAPControl **cctrls, + int *msgidp ) { BerElement *ber; int i, rc; + ber_int_t id; - /* - * An add request looks like this: - * AddRequest ::= SEQUENCE { - * entry DistinguishedName, - * attrs SEQUENCE OF SEQUENCE { - * type AttributeType, - * values SET OF AttributeValue - * } - * } - */ + Debug( LDAP_DEBUG_TRACE, "ldap_add_ext\n", 0, 0, 0 ); + assert( ld != NULL ); + assert( LDAP_VALID( ld ) ); + assert( dn != NULL ); + assert( msgidp != NULL ); - Debug( LDAP_DEBUG_TRACE, "ldap_add\n", 0, 0, 0 ); + /* check client controls */ + rc = ldap_int_client_controls( ld, cctrls ); + if( rc != LDAP_SUCCESS ) return rc; /* create a message to send */ - if ( (ber = ldap_alloc_ber_with_options( ld )) == NULLBER ) { - return( -1 ); + if ( (ber = ldap_alloc_ber_with_options( ld )) == NULL ) { + ld->ld_errno = LDAP_NO_MEMORY; + return ld->ld_errno; } - if ( ber_printf( ber, "{it{s{", ++ld->ld_msgid, LDAP_REQ_ADD, dn ) - == -1 ) { + LDAP_NEXT_MSGID(ld, id); + rc = ber_printf( ber, "{it{s{", /* '}}}' */ + id, LDAP_REQ_ADD, dn ); + + if ( rc == -1 ) { ld->ld_errno = LDAP_ENCODING_ERROR; ber_free( ber, 1 ); - return( -1 ); + return ld->ld_errno; } - /* for each attribute in the entry... */ - for ( i = 0; attrs[i] != NULL; i++ ) { - if ( ( attrs[i]->mod_op & LDAP_MOD_BVALUES) != 0 ) { - rc = ber_printf( ber, "{s[V]}", attrs[i]->mod_type, - attrs[i]->mod_values ); - } else { - rc = ber_printf( ber, "{s[v]}", attrs[i]->mod_type, - attrs[i]->mod_values ); - } - if ( rc == -1 ) { - ld->ld_errno = LDAP_ENCODING_ERROR; - ber_free( ber, 1 ); - return( -1 ); + /* allow attrs to be NULL ("touch"; should fail...) */ + if ( attrs ) { + /* for each attribute in the entry... */ + for ( i = 0; attrs[i] != NULL; i++ ) { + if ( ( attrs[i]->mod_op & LDAP_MOD_BVALUES) != 0 ) { + int j; + + if ( attrs[i]->mod_bvalues == NULL ) { + ld->ld_errno = LDAP_PARAM_ERROR; + ber_free( ber, 1 ); + return ld->ld_errno; + } + + for ( j = 0; attrs[i]->mod_bvalues[ j ] != NULL; j++ ) { + if ( attrs[i]->mod_bvalues[ j ]->bv_val == NULL ) { + ld->ld_errno = LDAP_PARAM_ERROR; + ber_free( ber, 1 ); + return ld->ld_errno; + } + } + + rc = ber_printf( ber, "{s[V]N}", attrs[i]->mod_type, + attrs[i]->mod_bvalues ); + + } else { + if ( attrs[i]->mod_values == NULL ) { + ld->ld_errno = LDAP_PARAM_ERROR; + ber_free( ber, 1 ); + return ld->ld_errno; + } + + rc = ber_printf( ber, "{s[v]N}", attrs[i]->mod_type, + attrs[i]->mod_values ); + } + if ( rc == -1 ) { + ld->ld_errno = LDAP_ENCODING_ERROR; + ber_free( ber, 1 ); + return ld->ld_errno; + } } } - if ( ber_printf( ber, "}}}" ) == -1 ) { + if ( ber_printf( ber, /*{{*/ "N}N}" ) == -1 ) { + ld->ld_errno = LDAP_ENCODING_ERROR; + ber_free( ber, 1 ); + return ld->ld_errno; + } + + /* Put Server Controls */ + if( ldap_int_put_controls( ld, sctrls, ber ) != LDAP_SUCCESS ) { + ber_free( ber, 1 ); + return ld->ld_errno; + } + + if ( ber_printf( ber, /*{*/ "N}" ) == -1 ) { ld->ld_errno = LDAP_ENCODING_ERROR; ber_free( ber, 1 ); - return( -1 ); + return ld->ld_errno; } /* send the message */ - return( ldap_send_initial_request( ld, LDAP_REQ_ADD, dn, ber )); + *msgidp = ldap_send_initial_request( ld, LDAP_REQ_ADD, dn, ber, id ); + + if(*msgidp < 0) + return ld->ld_errno; + + return LDAP_SUCCESS; } int -ldap_add_s( LDAP *ld, char *dn, LDAPMod **attrs ) +ldap_add_ext_s( + LDAP *ld, + LDAP_CONST char *dn, + LDAPMod **attrs, + LDAPControl **sctrls, + LDAPControl **cctrls ) { - int msgid; + int msgid, rc; LDAPMessage *res; - if ( (msgid = ldap_add( ld, dn, attrs )) == -1 ) - return( ld->ld_errno ); + rc = ldap_add_ext( ld, dn, attrs, sctrls, cctrls, &msgid ); + + if ( rc != LDAP_SUCCESS ) + return( rc ); - if ( ldap_result( ld, msgid, 1, (struct timeval *) NULL, &res ) == -1 ) + if ( ldap_result( ld, msgid, LDAP_MSG_ALL, (struct timeval *) NULL, &res ) == -1 || !res ) return( ld->ld_errno ); return( ldap_result2error( ld, res, 1 ) ); } +int +ldap_add_s( LDAP *ld, LDAP_CONST char *dn, LDAPMod **attrs ) +{ + return ldap_add_ext_s( ld, dn, attrs, NULL, NULL ); +} +