]>
Commit | Line | Data |
---|---|---|
e3d460c9 A |
1 | /* |
2 | * Copyright (c) 2015 Apple Inc. All Rights Reserved. | |
3 | * | |
4 | * @APPLE_LICENSE_HEADER_START@ | |
5 | * | |
6 | * This file contains Original Code and/or Modifications of Original Code | |
7 | * as defined in and that are subject to the Apple Public Source License | |
8 | * Version 2.0 (the 'License'). You may not use this file except in | |
9 | * compliance with the License. Please obtain a copy of the License at | |
10 | * http://www.opensource.apple.com/apsl/ and read it before using this | |
11 | * file. | |
12 | * | |
13 | * The Original Code and all software distributed under the License are | |
14 | * distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER | |
15 | * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES, | |
16 | * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY, | |
17 | * FITNESS FOR A PARTICULAR PURPOSE, QUIET ENJOYMENT OR NON-INFRINGEMENT. | |
18 | * Please see the License for the specific language governing rights and | |
19 | * limitations under the License. | |
20 | * | |
21 | * @APPLE_LICENSE_HEADER_END@ | |
22 | */ | |
23 | ||
24 | #include "CSPDLTransaction.h" | |
25 | #include <Security/SecBasePriv.h> | |
26 | #include <syslog.h> | |
27 | ||
28 | DLTransaction::DLTransaction(CSSM_DL_DB_HANDLE dldbh) | |
29 | : mDldbh(dldbh), mSuccess(false), mFinalized(false), mAutoCommit(CSSM_TRUE) { | |
30 | initialize(); | |
31 | } | |
32 | ||
33 | DLTransaction::DLTransaction() | |
34 | : mSuccess(false), mFinalized(false), mAutoCommit(CSSM_TRUE) { | |
35 | } | |
36 | ||
37 | void DLTransaction::initialize() { | |
38 | // Turn off autocommit on the underlying DL and remember the old state. | |
39 | Security::CssmClient::ObjectImpl::check(CSSM_DL_PassThrough(mDldbh, | |
40 | CSSM_APPLEFILEDL_TOGGLE_AUTOCOMMIT, | |
41 | NULL, reinterpret_cast<void **>(&mAutoCommit))); | |
42 | } | |
43 | ||
44 | DLTransaction::~DLTransaction() { | |
45 | finalize(); | |
46 | } | |
47 | ||
48 | void DLTransaction::success() { | |
49 | mSuccess = true; | |
50 | } | |
51 | ||
52 | void DLTransaction::finalize() { | |
53 | if(mFinalized) { | |
54 | return; | |
55 | } | |
56 | ||
57 | // If autocommit wasn't on on the database when we started, don't | |
58 | // actually commit. There might be something else going on... | |
59 | if(mAutoCommit) { | |
60 | // if this transaction was a success, commit. Otherwise, roll back. | |
61 | if(mSuccess) { | |
62 | Security::CssmClient::ObjectImpl::check(CSSM_DL_PassThrough(mDldbh, | |
63 | CSSM_APPLEFILEDL_COMMIT, NULL, NULL)); | |
64 | CSSM_DL_PassThrough(mDldbh, CSSM_APPLEFILEDL_TOGGLE_AUTOCOMMIT, | |
65 | reinterpret_cast<const void *>(mAutoCommit), NULL); | |
66 | } else { | |
67 | // This is a failed transaction. Roll back, and turn autoCommit back on. | |
68 | // | |
69 | // Note that we're likely (but not necessarily) unwinding the stack for an exception right now. | |
70 | // (If this transaction succeeded, we wouldn't be here. So, it failed, and this code likes to fail with exceptions.) | |
71 | // If this throws an exception, we might crash the whole process. | |
72 | // Swallow exceptions whole, but log them aggressively. | |
73 | try { | |
74 | CSSM_DL_PassThrough(mDldbh, CSSM_APPLEFILEDL_ROLLBACK, NULL, NULL); | |
75 | CSSM_DL_PassThrough(mDldbh, CSSM_APPLEFILEDL_TOGGLE_AUTOCOMMIT, | |
76 | reinterpret_cast<const void *>(mAutoCommit), NULL); | |
77 | } catch(CssmError cssme) { | |
78 | const char* errStr = cssmErrorString(cssme.error); | |
79 | secdebugfunc("integrity", "caught CssmError during transaction rollback: %d %s", (int) cssme.error, errStr); | |
80 | syslog(LOG_ERR, "ERROR: failed to rollback keychain transaction: %d %s", (int) cssme.error, errStr); | |
81 | } | |
82 | } | |
83 | } | |
84 | mFinalized = true; | |
85 | } | |
86 | ||
87 | ||
88 | CSPDLTransaction::CSPDLTransaction(Security::CssmClient::Db& db) | |
89 | : DLTransaction(), mDb(db) { | |
90 | // Get the handle of the DL underlying this CSPDL. | |
91 | mDb->passThrough(CSSM_APPLECSPDL_DB_GET_HANDLE, NULL, | |
92 | reinterpret_cast<void **>(&mDldbh)); | |
93 | ||
94 | initialize(); | |
95 | } | |
96 | ||
97 | CSPDLTransaction::~CSPDLTransaction() { | |
98 | finalize(); | |
99 | } | |
100 |