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