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