Line data Source code
1 : /*
2 : Unit tests for the dsdb group auditing code in group_audit.c
3 :
4 : Copyright (C) Andrew Bartlett <abartlet@samba.org> 2018
5 :
6 : This program is free software; you can redistribute it and/or modify
7 : it under the terms of the GNU General Public License as published by
8 : the Free Software Foundation; either version 3 of the License, or
9 : (at your option) any later version.
10 :
11 : This program is distributed in the hope that it will be useful,
12 : but WITHOUT ANY WARRANTY; without even the implied warranty of
13 : MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 : GNU General Public License for more details.
15 :
16 : You should have received a copy of the GNU General Public License
17 : along with this program. If not, see <http://www.gnu.org/licenses/>.
18 : */
19 :
20 : /*
21 : * These tests exercise the error handling routines.
22 : */
23 :
24 : #include <stdarg.h>
25 : #include <stddef.h>
26 : #include <setjmp.h>
27 : #include <unistd.h>
28 : #include <cmocka.h>
29 :
30 : int ldb_group_audit_log_module_init(const char *version);
31 : #include "../group_audit.c"
32 :
33 : #include "lib/ldb/include/ldb_private.h"
34 :
35 : /*
36 : * cmocka wrappers for json_new_object
37 : */
38 : struct json_object __wrap_json_new_object(void);
39 : struct json_object __real_json_new_object(void);
40 8 : struct json_object __wrap_json_new_object(void)
41 : {
42 :
43 8 : bool use_real = (bool)mock();
44 8 : if (!use_real) {
45 2 : return json_empty_object;
46 : }
47 6 : return __real_json_new_object();
48 : }
49 :
50 : /*
51 : * cmocka wrappers for json_add_version
52 : */
53 : int __wrap_json_add_version(struct json_object *object, int major, int minor);
54 : int __real_json_add_version(struct json_object *object, int major, int minor);
55 4 : int __wrap_json_add_version(struct json_object *object, int major, int minor)
56 : {
57 :
58 4 : int ret = (int)mock();
59 4 : if (ret) {
60 : return ret;
61 : }
62 3 : return __real_json_add_version(object, major, minor);
63 : }
64 :
65 : /*
66 : * cmocka wrappers for json_add_version
67 : */
68 : int __wrap_json_add_timestamp(struct json_object *object);
69 : int __real_json_add_timestamp(struct json_object *object);
70 2 : int __wrap_json_add_timestamp(struct json_object *object)
71 : {
72 :
73 2 : int ret = (int)mock();
74 2 : if (ret) {
75 : return ret;
76 : }
77 1 : return __real_json_add_timestamp(object);
78 : }
79 :
80 : /*
81 : * Test helper to add a session id and user SID
82 : */
83 1 : static void add_session_data(
84 : TALLOC_CTX *ctx,
85 : struct ldb_context *ldb,
86 : const char *session,
87 : const char *user_sid)
88 : {
89 1 : struct auth_session_info *sess = NULL;
90 1 : struct security_token *token = NULL;
91 1 : struct dom_sid *sid = NULL;
92 1 : struct GUID session_id;
93 1 : bool ok;
94 :
95 1 : sess = talloc_zero(ctx, struct auth_session_info);
96 1 : token = talloc_zero(ctx, struct security_token);
97 1 : sid = talloc_zero(ctx, struct dom_sid);
98 1 : ok = string_to_sid(sid, user_sid);
99 1 : assert_true(ok);
100 1 : token->sids = sid;
101 1 : sess->security_token = token;
102 1 : GUID_from_string(session, &session_id);
103 1 : sess->unique_session_token = session_id;
104 1 : ldb_set_opaque(ldb, DSDB_SESSION_INFO, sess);
105 1 : }
106 :
107 : /*
108 : * Test helper to insert a transaction_id into a request.
109 : */
110 1 : static void add_transaction_id(struct ldb_request *req, const char *id)
111 : {
112 1 : struct GUID guid;
113 1 : struct dsdb_control_transaction_identifier *transaction_id = NULL;
114 :
115 1 : transaction_id = talloc_zero(
116 : req,
117 : struct dsdb_control_transaction_identifier);
118 1 : assert_non_null(transaction_id);
119 1 : GUID_from_string(id, &guid);
120 1 : transaction_id->transaction_guid = guid;
121 1 : ldb_request_add_control(
122 : req,
123 : DSDB_CONTROL_TRANSACTION_IDENTIFIER_OID,
124 : false,
125 : transaction_id);
126 1 : }
127 :
128 1 : static void test_audit_group_json(void **state)
129 : {
130 1 : struct ldb_context *ldb = NULL;
131 1 : struct ldb_module *module = NULL;
132 1 : struct ldb_request *req = NULL;
133 :
134 1 : struct tsocket_address *ts = NULL;
135 :
136 1 : const char *const SID = "S-1-5-21-2470180966-3899876309-2637894779";
137 1 : const char * const SESSION = "7130cb06-2062-6a1b-409e-3514c26b1773";
138 :
139 1 : struct GUID transaction_id;
140 1 : const char *const TRANSACTION = "7130cb06-2062-6a1b-409e-3514c26b1773";
141 :
142 1 : enum event_id_type event_id = EVT_ID_USER_REMOVED_FROM_GLOBAL_SEC_GROUP;
143 :
144 1 : struct json_object json;
145 :
146 1 : TALLOC_CTX *ctx = talloc_new(NULL);
147 :
148 1 : ldb = ldb_init(ctx, NULL);
149 :
150 1 : GUID_from_string(TRANSACTION, &transaction_id);
151 :
152 1 : module = talloc_zero(ctx, struct ldb_module);
153 1 : module->ldb = ldb;
154 :
155 1 : tsocket_address_inet_from_strings(ctx, "ip", "127.0.0.1", 0, &ts);
156 1 : ldb_set_opaque(ldb, "remoteAddress", ts);
157 :
158 1 : add_session_data(ctx, ldb, SESSION, SID);
159 :
160 1 : req = talloc_zero(ctx, struct ldb_request);
161 1 : req->operation = LDB_ADD;
162 1 : add_transaction_id(req, TRANSACTION);
163 :
164 : /*
165 : * Fail on the creation of the audit json object
166 : */
167 :
168 1 : will_return(__wrap_json_new_object, false);
169 :
170 1 : json = audit_group_json(module,
171 : req,
172 : "the-action",
173 : "the-user-name",
174 : "the-group-name",
175 : event_id,
176 : LDB_ERR_OPERATIONS_ERROR);
177 1 : assert_true(json_is_invalid(&json));
178 :
179 : /*
180 : * Fail adding the version object .
181 : */
182 :
183 1 : will_return(__wrap_json_new_object, true);
184 1 : will_return(__wrap_json_add_version, JSON_ERROR);
185 :
186 1 : json = audit_group_json(module,
187 : req,
188 : "the-action",
189 : "the-user-name",
190 : "the-group-name",
191 : event_id,
192 : LDB_ERR_OPERATIONS_ERROR);
193 1 : assert_true(json_is_invalid(&json));
194 :
195 : /*
196 : * Fail on creation of the wrapper.
197 : */
198 :
199 1 : will_return(__wrap_json_new_object, true);
200 1 : will_return(__wrap_json_add_version, 0);
201 1 : will_return(__wrap_json_new_object, false);
202 :
203 1 : json = audit_group_json(module,
204 : req,
205 : "the-action",
206 : "the-user-name",
207 : "the-group-name",
208 : event_id,
209 : LDB_ERR_OPERATIONS_ERROR);
210 1 : assert_true(json_is_invalid(&json));
211 :
212 : /*
213 : * Fail adding the timestamp to the wrapper object.
214 : */
215 1 : will_return(__wrap_json_new_object, true);
216 1 : will_return(__wrap_json_add_version, 0);
217 1 : will_return(__wrap_json_new_object, true);
218 1 : will_return(__wrap_json_add_timestamp, JSON_ERROR);
219 :
220 1 : json = audit_group_json(module,
221 : req,
222 : "the-action",
223 : "the-user-name",
224 : "the-group-name",
225 : event_id,
226 : LDB_ERR_OPERATIONS_ERROR);
227 1 : assert_true(json_is_invalid(&json));
228 :
229 :
230 : /*
231 : * Now test the happy path
232 : */
233 1 : will_return(__wrap_json_new_object, true);
234 1 : will_return(__wrap_json_add_version, 0);
235 1 : will_return(__wrap_json_new_object, true);
236 1 : will_return(__wrap_json_add_timestamp, 0);
237 :
238 1 : json = audit_group_json(module,
239 : req,
240 : "the-action",
241 : "the-user-name",
242 : "the-group-name",
243 : event_id,
244 : LDB_ERR_OPERATIONS_ERROR);
245 1 : assert_false(json_is_invalid(&json));
246 :
247 1 : json_free(&json);
248 1 : TALLOC_FREE(ctx);
249 :
250 1 : }
251 :
252 : /*
253 : * Note: to run under valgrind us:
254 : * valgrind --suppressions=test_group_audit.valgrind bin/test_group_audit
255 : * This suppresses the errors generated because the ldb_modules are not
256 : * de-registered.
257 : *
258 : */
259 1 : int main(void) {
260 1 : const struct CMUnitTest tests[] = {
261 : cmocka_unit_test(test_audit_group_json),
262 : };
263 :
264 1 : cmocka_set_message_output(CM_OUTPUT_SUBUNIT);
265 1 : return cmocka_run_group_tests(tests, NULL, NULL);
266 : }
|