s4 group_audit: Add Windows Event Id's to Group membership changes
[metze/samba-autobuild/.git] / source4 / dsdb / samdb / ldb_modules / tests / test_group_audit_errors.c
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 struct json_object __wrap_json_new_object(void)
41 {
42
43         bool use_real = (bool)mock();
44         if (!use_real) {
45                 return json_empty_object;
46         }
47         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 int __wrap_json_add_version(struct json_object *object, int major, int minor)
56 {
57
58         int ret = (int)mock();
59         if (ret) {
60                 return ret;
61         }
62         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 int __wrap_json_add_timestamp(struct json_object *object)
71 {
72
73         int ret = (int)mock();
74         if (ret) {
75                 return ret;
76         }
77         return __real_json_add_timestamp(object);
78 }
79
80 /*
81  * Test helper to add a session id and user SID
82  */
83 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         struct auth_session_info *sess = NULL;
90         struct security_token *token = NULL;
91         struct dom_sid *sid = NULL;
92         struct GUID session_id;
93         bool ok;
94
95         sess = talloc_zero(ctx, struct auth_session_info);
96         token = talloc_zero(ctx, struct security_token);
97         sid = talloc_zero(ctx, struct dom_sid);
98         ok = string_to_sid(sid, user_sid);
99         assert_true(ok);
100         token->sids = sid;
101         sess->security_token = token;
102         GUID_from_string(session, &session_id);
103         sess->unique_session_token = session_id;
104         ldb_set_opaque(ldb, DSDB_SESSION_INFO, sess);
105 }
106
107 /*
108  * Test helper to insert a transaction_id into a request.
109  */
110 static void add_transaction_id(struct ldb_request *req, const char *id)
111 {
112         struct GUID guid;
113         struct dsdb_control_transaction_identifier *transaction_id = NULL;
114
115         transaction_id = talloc_zero(
116                 req,
117                 struct dsdb_control_transaction_identifier);
118         assert_non_null(transaction_id);
119         GUID_from_string(id, &guid);
120         transaction_id->transaction_guid = guid;
121         ldb_request_add_control(
122                 req,
123                 DSDB_CONTROL_TRANSACTION_IDENTIFIER_OID,
124                 false,
125                 transaction_id);
126 }
127
128 static void test_audit_group_json(void **state)
129 {
130         struct ldb_context *ldb = NULL;
131         struct ldb_module  *module = NULL;
132         struct ldb_request *req = NULL;
133
134         struct tsocket_address *ts = NULL;
135
136         const char *const SID = "S-1-5-21-2470180966-3899876309-2637894779";
137         const char * const SESSION = "7130cb06-2062-6a1b-409e-3514c26b1773";
138
139         struct GUID transaction_id;
140         const char *const TRANSACTION = "7130cb06-2062-6a1b-409e-3514c26b1773";
141
142         enum event_id_type event_id = EVT_ID_USER_REMOVED_FROM_GLOBAL_SEC_GROUP;
143
144         struct json_object json;
145
146         TALLOC_CTX *ctx = talloc_new(NULL);
147
148         ldb = ldb_init(ctx, NULL);
149
150         GUID_from_string(TRANSACTION, &transaction_id);
151
152         module = talloc_zero(ctx, struct ldb_module);
153         module->ldb = ldb;
154
155         tsocket_address_inet_from_strings(ctx, "ip", "127.0.0.1", 0, &ts);
156         ldb_set_opaque(ldb, "remoteAddress", ts);
157
158         add_session_data(ctx, ldb, SESSION, SID);
159
160         req = talloc_zero(ctx, struct ldb_request);
161         req->operation =  LDB_ADD;
162         add_transaction_id(req, TRANSACTION);
163
164         /*
165          * Fail on the creation of the audit json object
166          */
167
168         will_return(__wrap_json_new_object, false);
169
170         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         assert_true(json_is_invalid(&json));
178
179         /*
180          * Fail adding the version object .
181          */
182
183         will_return(__wrap_json_new_object, true);
184         will_return(__wrap_json_add_version, JSON_ERROR);
185
186         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         assert_true(json_is_invalid(&json));
194
195         /*
196          * Fail on creation of the wrapper.
197          */
198
199         will_return(__wrap_json_new_object, true);
200         will_return(__wrap_json_add_version, 0);
201         will_return(__wrap_json_new_object, false);
202
203         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         assert_true(json_is_invalid(&json));
211
212         /*
213          * Fail adding the timestamp to the wrapper object.
214          */
215         will_return(__wrap_json_new_object, true);
216         will_return(__wrap_json_add_version, 0);
217         will_return(__wrap_json_new_object, true);
218         will_return(__wrap_json_add_timestamp, JSON_ERROR);
219
220         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         assert_true(json_is_invalid(&json));
228
229
230         /*
231          * Now test the happy path
232          */
233         will_return(__wrap_json_new_object, true);
234         will_return(__wrap_json_add_version, 0);
235         will_return(__wrap_json_new_object, true);
236         will_return(__wrap_json_add_timestamp, 0);
237
238         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         assert_false(json_is_invalid(&json));
246
247         json_free(&json);
248         TALLOC_FREE(ctx);
249
250 }
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 int main(void) {
260         const struct CMUnitTest tests[] = {
261                 cmocka_unit_test(test_audit_group_json),
262         };
263
264         cmocka_set_message_output(CM_OUTPUT_SUBUNIT);
265         return cmocka_run_group_tests(tests, NULL, NULL);
266 }