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