1/* $OpenLDAP$ */ 2/* This work is part of OpenLDAP Software <http://www.openldap.org/>. 3 * 4 * Copyright 2006-2011 The OpenLDAP Foundation. 5 * All rights reserved. 6 * 7 * Redistribution and use in source and binary forms, with or without 8 * modification, are permitted only as authorized by the OpenLDAP 9 * Public License. 10 * 11 * A copy of this license is available in the file LICENSE in the 12 * top-level directory of the distribution or, alternatively, at 13 * <http://www.OpenLDAP.org/license.html>. 14 */ 15/* ACKNOWLEDGEMENTS: 16 * This program was orignally developed by Kurt D. Zeilenga for inclusion 17 * in OpenLDAP Software. 18 */ 19 20/* 21 * LDAPv3 Transactions (draft-zeilenga-ldap-txn) 22 */ 23 24#include "portable.h" 25 26#include <stdio.h> 27#include <ac/stdlib.h> 28 29#include <ac/socket.h> 30#include <ac/string.h> 31#include <ac/time.h> 32 33#include "ldap-int.h" 34#include "ldap_log.h" 35 36#ifdef LDAP_X_TXN 37int 38ldap_txn_start( 39 LDAP *ld, 40 LDAPControl **sctrls, 41 LDAPControl **cctrls, 42 int *msgidp ) 43{ 44 return ldap_extended_operation( ld, LDAP_EXOP_X_TXN_START, 45 NULL, sctrls, cctrls, msgidp ); 46} 47 48int 49ldap_txn_start_s( 50 LDAP *ld, 51 LDAPControl **sctrls, 52 LDAPControl **cctrls, 53 struct berval **txnid ) 54{ 55 assert( txnid != NULL ); 56 57 return ldap_extended_operation_s( ld, LDAP_EXOP_X_TXN_START, 58 NULL, sctrls, cctrls, NULL, txnid ); 59} 60 61int 62ldap_txn_end( 63 LDAP *ld, 64 int commit, 65 struct berval *txnid, 66 LDAPControl **sctrls, 67 LDAPControl **cctrls, 68 int *msgidp ) 69{ 70 int rc; 71 BerElement *txnber = NULL; 72 struct berval *txnval = NULL; 73 74 assert( txnid != NULL ); 75 76 txnber = ber_alloc_t( LBER_USE_DER ); 77 78 if( commit ) { 79 ber_printf( txnber, "{ON}", txnid ); 80 } else { 81 ber_printf( txnber, "{bON}", commit, txnid ); 82 } 83 84 ber_flatten( txnber, &txnval ); 85 86 rc = ldap_extended_operation( ld, LDAP_EXOP_X_TXN_END, 87 txnval, sctrls, cctrls, msgidp ); 88 89 ber_free( txnber, 1 ); 90 return rc; 91} 92 93int 94ldap_txn_end_s( 95 LDAP *ld, 96 int commit, 97 struct berval *txnid, 98 LDAPControl **sctrls, 99 LDAPControl **cctrls, 100 int *retidp ) 101{ 102 int rc; 103 BerElement *txnber = NULL; 104 struct berval *txnval = NULL; 105 struct berval *retdata = NULL; 106 107 if ( retidp != NULL ) *retidp = -1; 108 109 txnber = ber_alloc_t( LBER_USE_DER ); 110 111 if( commit ) { 112 ber_printf( txnber, "{ON}", txnid ); 113 } else { 114 ber_printf( txnber, "{bON}", commit, txnid ); 115 } 116 117 ber_flatten( txnber, &txnval ); 118 119 rc = ldap_extended_operation_s( ld, LDAP_EXOP_X_TXN_END, 120 txnval, sctrls, cctrls, NULL, &retdata ); 121 122 ber_free( txnber, 1 ); 123 124 /* parse retdata */ 125 if( retdata != NULL ) { 126 BerElement *ber; 127 ber_tag_t tag; 128 ber_int_t retid; 129 130 if( retidp == NULL ) goto done; 131 132 ber = ber_init( retdata ); 133 134 if( ber == NULL ) { 135 rc = ld->ld_errno = LDAP_NO_MEMORY; 136 goto done; 137 } 138 139 tag = ber_scanf( ber, "i", &retid ); 140 ber_free( ber, 1 ); 141 142 if ( tag != LBER_INTEGER ) { 143 rc = ld->ld_errno = LDAP_DECODING_ERROR; 144 goto done; 145 } 146 147 *retidp = (int) retid; 148 149done: 150 ber_bvfree( retdata ); 151 } 152 153 return rc; 154} 155#endif 156