1 /* $OpenLDAP$ */
2 /* This work is part of OpenLDAP Software <http://www.openldap.org/>.
3 *
4 * Copyright 2006-2021 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 originally 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 int
ldap_txn_start(LDAP * ld,LDAPControl ** sctrls,LDAPControl ** cctrls,int * msgidp)37 ldap_txn_start(
38 LDAP *ld,
39 LDAPControl **sctrls,
40 LDAPControl **cctrls,
41 int *msgidp )
42 {
43 return ldap_extended_operation( ld, LDAP_EXOP_TXN_START,
44 NULL, sctrls, cctrls, msgidp );
45 }
46
47 int
ldap_txn_start_s(LDAP * ld,LDAPControl ** sctrls,LDAPControl ** cctrls,struct berval ** txnid)48 ldap_txn_start_s(
49 LDAP *ld,
50 LDAPControl **sctrls,
51 LDAPControl **cctrls,
52 struct berval **txnid )
53 {
54 assert( txnid != NULL );
55
56 return ldap_extended_operation_s( ld, LDAP_EXOP_TXN_START,
57 NULL, sctrls, cctrls, NULL, txnid );
58 }
59
60 int
ldap_txn_end(LDAP * ld,int commit,struct berval * txnid,LDAPControl ** sctrls,LDAPControl ** cctrls,int * msgidp)61 ldap_txn_end(
62 LDAP *ld,
63 int commit,
64 struct berval *txnid,
65 LDAPControl **sctrls,
66 LDAPControl **cctrls,
67 int *msgidp )
68 {
69 int rc;
70 BerElement *txnber = NULL;
71 struct berval *txnval = NULL;
72
73 assert( txnid != NULL );
74
75 txnber = ber_alloc_t( LBER_USE_DER );
76
77 if( commit ) {
78 ber_printf( txnber, "{ON}", txnid );
79 } else {
80 ber_printf( txnber, "{bON}", commit, txnid );
81 }
82
83 ber_flatten( txnber, &txnval );
84
85 rc = ldap_extended_operation( ld, LDAP_EXOP_TXN_END,
86 txnval, sctrls, cctrls, msgidp );
87
88 ber_free( txnber, 1 );
89 return rc;
90 }
91
92 int
ldap_txn_end_s(LDAP * ld,int commit,struct berval * txnid,LDAPControl ** sctrls,LDAPControl ** cctrls,int * retidp)93 ldap_txn_end_s(
94 LDAP *ld,
95 int commit,
96 struct berval *txnid,
97 LDAPControl **sctrls,
98 LDAPControl **cctrls,
99 int *retidp )
100 {
101 int rc;
102 BerElement *txnber = NULL;
103 struct berval *txnval = NULL;
104 struct berval *retdata = NULL;
105
106 if ( retidp != NULL ) *retidp = -1;
107
108 txnber = ber_alloc_t( LBER_USE_DER );
109
110 if( commit ) {
111 ber_printf( txnber, "{ON}", txnid );
112 } else {
113 ber_printf( txnber, "{bON}", commit, txnid );
114 }
115
116 ber_flatten( txnber, &txnval );
117
118 rc = ldap_extended_operation_s( ld, LDAP_EXOP_TXN_END,
119 txnval, sctrls, cctrls, NULL, &retdata );
120
121 ber_free( txnber, 1 );
122
123 /* parse retdata */
124 if( retdata != NULL ) {
125 BerElement *ber;
126 ber_tag_t tag;
127 ber_int_t retid;
128
129 if( retidp == NULL ) goto done;
130
131 ber = ber_init( retdata );
132
133 if( ber == NULL ) {
134 rc = ld->ld_errno = LDAP_NO_MEMORY;
135 goto done;
136 }
137
138 tag = ber_scanf( ber, "i", &retid );
139 ber_free( ber, 1 );
140
141 if ( tag != LBER_INTEGER ) {
142 rc = ld->ld_errno = LDAP_DECODING_ERROR;
143 goto done;
144 }
145
146 *retidp = (int) retid;
147
148 done:
149 ber_bvfree( retdata );
150 }
151
152 return rc;
153 }
154