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