txn.c revision 1.4 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