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
41 int
ldap_txn_start(LDAP * ld,LDAPControl ** sctrls,LDAPControl ** cctrls,int * msgidp)42 ldap_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
52 int
ldap_txn_start_s(LDAP * ld,LDAPControl ** sctrls,LDAPControl ** cctrls,struct berval ** txnid)53 ldap_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
65 int
ldap_txn_end(LDAP * ld,int commit,struct berval * txnid,LDAPControl ** sctrls,LDAPControl ** cctrls,int * msgidp)66 ldap_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
97 int
ldap_txn_end_s(LDAP * ld,int commit,struct berval * txnid,LDAPControl ** sctrls,LDAPControl ** cctrls,int * retidp)98 ldap_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
153 done:
154 ber_bvfree( retdata );
155 }
156
157 return rc;
158 }
159