Line data Source code
1 : /*
2 :
3 : Authentication and authorization logging
4 :
5 : Copyright (C) Andrew Bartlett <abartlet@samba.org> 2017
6 :
7 : This program is free software; you can redistribute it and/or modify
8 : it under the terms of the GNU General Public License as published by
9 : the Free Software Foundation; either version 3 of the License, or
10 : (at your option) any later version.
11 :
12 : This program is distributed in the hope that it will be useful,
13 : but WITHOUT ANY WARRANTY; without even the implied warranty of
14 : MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15 : GNU General Public License for more details.
16 :
17 : You should have received a copy of the GNU General Public License
18 : along with this program. If not, see <http://www.gnu.org/licenses/>.
19 : */
20 :
21 : /*
22 : * Debug log levels for authentication logging (these both map to
23 : * LOG_NOTICE in syslog)
24 : */
25 : #define AUTH_FAILURE_LEVEL 2
26 : #define AUTH_SUCCESS_LEVEL 3
27 : #define AUTHZ_SUCCESS_LEVEL 4
28 : #define KDC_AUTHZ_FAILURE_LEVEL 2
29 : #define KDC_AUTHZ_SUCCESS_LEVEL 3
30 :
31 : /* 5 is used for both authentication and authorization */
32 : #define AUTH_ANONYMOUS_LEVEL 5
33 : #define AUTHZ_ANONYMOUS_LEVEL 5
34 :
35 : #define AUTHZ_JSON_TYPE "Authorization"
36 : #define AUTH_JSON_TYPE "Authentication"
37 : #define KDC_AUTHZ_JSON_TYPE "KDC Authorization"
38 :
39 : /*
40 : * JSON message version numbers
41 : *
42 : * If adding a field increment the minor version
43 : * If removing or changing the format/meaning of a field
44 : * increment the major version.
45 : */
46 : #define AUTH_MAJOR 1
47 : #define AUTH_MINOR 3
48 : #define AUTHZ_MAJOR 1
49 : #define AUTHZ_MINOR 2
50 : #define KDC_AUTHZ_MAJOR 1
51 : #define KDC_AUTHZ_MINOR 0
52 :
53 : #include "includes.h"
54 : #include "../lib/tsocket/tsocket.h"
55 : #include "common_auth.h"
56 : #include "lib/util/util_str_escape.h"
57 : #include "libcli/security/dom_sid.h"
58 : #include "libcli/security/security_token.h"
59 : #include "librpc/gen_ndr/server_id.h"
60 : #include "source4/lib/messaging/messaging.h"
61 : #include "source4/lib/messaging/irpc.h"
62 : #include "lib/util/server_id_db.h"
63 : #include "lib/param/param.h"
64 : #include "librpc/ndr/libndr.h"
65 : #include "librpc/gen_ndr/windows_event_ids.h"
66 : #include "lib/audit_logging/audit_logging.h"
67 :
68 : /*
69 : * Determine the type of the password supplied for the
70 : * authorisation attempt.
71 : *
72 : */
73 : static const char* get_password_type(const struct auth_usersupplied_info *ui);
74 :
75 : #ifdef HAVE_JANSSON
76 :
77 : #include <jansson.h>
78 : #include "system/time.h"
79 :
80 : /*
81 : * Write the json object to the debug logs.
82 : *
83 : */
84 136571 : static void log_json(struct imessaging_context *msg_ctx,
85 : struct loadparm_context *lp_ctx,
86 : struct json_object *object,
87 : int debug_class,
88 : int debug_level)
89 : {
90 136571 : audit_log_json(object, debug_class, debug_level);
91 136571 : if (msg_ctx && lp_ctx && lpcfg_auth_event_notification(lp_ctx)) {
92 136571 : audit_message_send(msg_ctx,
93 : AUTH_EVENT_NAME,
94 : MSG_AUTH_LOG,
95 : object);
96 : }
97 136571 : }
98 :
99 : /*
100 : * Determine the Windows logon type for the current authorisation attempt.
101 : *
102 : * Currently Samba only supports
103 : *
104 : * 2 Interactive A user logged on to this computer.
105 : * 3 Network A user or computer logged on to this computer from
106 : * the network.
107 : * 8 NetworkCleartext A user logged on to this computer from the network.
108 : * The user's password was passed to the authentication
109 : * package in its unhashed form.
110 : *
111 : */
112 50272 : static enum event_logon_type get_logon_type(
113 : const struct auth_usersupplied_info *ui)
114 : {
115 50272 : if ((ui->logon_parameters & MSV1_0_CLEARTEXT_PASSWORD_SUPPLIED)
116 49950 : || (ui->password_state == AUTH_PASSWORD_PLAIN)) {
117 322 : return EVT_LOGON_NETWORK_CLEAR_TEXT;
118 49950 : } else if (ui->flags & USER_INFO_INTERACTIVE_LOGON) {
119 540 : return EVT_LOGON_INTERACTIVE;
120 : }
121 46598 : return EVT_LOGON_NETWORK;
122 : }
123 :
124 : /*
125 : * Write a machine parsable json formatted authentication log entry.
126 : *
127 : * IF removing or changing the format/meaning of a field please update the
128 : * major version number AUTH_MAJOR
129 : *
130 : * IF adding a new field please update the minor version number AUTH_MINOR
131 : *
132 : * To process the resulting log lines from the command line use jq to
133 : * parse the json.
134 : *
135 : * grep "^ {" log file |
136 : * jq -rc '"\(.timestamp)\t\(.Authentication.status)\t
137 : * \(.Authentication.clientDomain)\t
138 : * \(.Authentication.clientAccount)
139 : * \t\(.Authentication.workstation)
140 : * \t\(.Authentication.remoteAddress)
141 : * \t\(.Authentication.localAddress)"'
142 : */
143 50272 : static void log_authentication_event_json(
144 : struct imessaging_context *msg_ctx,
145 : struct loadparm_context *lp_ctx,
146 : const struct timeval *start_time,
147 : const struct auth_usersupplied_info *ui,
148 : NTSTATUS status,
149 : const char *domain_name,
150 : const char *account_name,
151 : struct dom_sid *sid,
152 : const struct authn_audit_info *client_audit_info,
153 : const struct authn_audit_info *server_audit_info,
154 : enum event_id_type event_id,
155 : int debug_level)
156 : {
157 50272 : struct json_object wrapper = json_empty_object;
158 50272 : struct json_object authentication = json_empty_object;
159 50272 : struct json_object client_policy = json_null_object();
160 50272 : struct json_object server_policy = json_null_object();
161 2812 : char logon_id[19];
162 50272 : int rc = 0;
163 100544 : const char *clientDomain = ui->orig_client.domain_name ?
164 50272 : ui->orig_client.domain_name :
165 : ui->client.domain_name;
166 100544 : const char *clientAccount = ui->orig_client.account_name ?
167 50272 : ui->orig_client.account_name :
168 : ui->client.account_name;
169 :
170 50272 : authentication = json_new_object();
171 50272 : if (json_is_invalid(&authentication)) {
172 0 : goto failure;
173 : }
174 50272 : rc = json_add_version(&authentication, AUTH_MAJOR, AUTH_MINOR);
175 50272 : if (rc != 0) {
176 0 : goto failure;
177 : }
178 50272 : rc = json_add_int(&authentication,
179 : "eventId",
180 : event_id);
181 50272 : if (rc != 0) {
182 0 : goto failure;
183 : }
184 50272 : snprintf(logon_id,
185 : sizeof( logon_id),
186 : "%"PRIx64"",
187 50272 : ui->logon_id);
188 50272 : rc = json_add_string(&authentication, "logonId", logon_id);
189 50272 : if (rc != 0) {
190 0 : goto failure;
191 : }
192 53084 : rc = json_add_int(&authentication, "logonType", get_logon_type(ui));
193 50272 : if (rc != 0) {
194 0 : goto failure;
195 : }
196 50272 : rc = json_add_string(&authentication, "status", nt_errstr(status));
197 50272 : if (rc != 0) {
198 0 : goto failure;
199 : }
200 50272 : rc = json_add_address(&authentication, "localAddress", ui->local_host);
201 50272 : if (rc != 0) {
202 0 : goto failure;
203 : }
204 2812 : rc =
205 50272 : json_add_address(&authentication, "remoteAddress", ui->remote_host);
206 50272 : if (rc != 0) {
207 0 : goto failure;
208 : }
209 53084 : rc = json_add_string(
210 50272 : &authentication, "serviceDescription", ui->service_description);
211 50272 : if (rc != 0) {
212 0 : goto failure;
213 : }
214 53084 : rc = json_add_string(
215 50272 : &authentication, "authDescription", ui->auth_description);
216 50272 : if (rc != 0) {
217 0 : goto failure;
218 : }
219 50272 : rc = json_add_string(
220 : &authentication, "clientDomain", clientDomain);
221 50272 : if (rc != 0) {
222 0 : goto failure;
223 : }
224 50272 : rc = json_add_string(
225 : &authentication, "clientAccount", clientAccount);
226 50272 : if (rc != 0) {
227 0 : goto failure;
228 : }
229 53084 : rc = json_add_string(
230 50272 : &authentication, "workstation", ui->workstation_name);
231 50272 : if (rc != 0) {
232 0 : goto failure;
233 : }
234 50272 : rc = json_add_string(&authentication, "becameAccount", account_name);
235 50272 : if (rc != 0) {
236 0 : goto failure;
237 : }
238 50272 : rc = json_add_string(&authentication, "becameDomain", domain_name);
239 50272 : if (rc != 0) {
240 0 : goto failure;
241 : }
242 50272 : rc = json_add_sid(&authentication, "becameSid", sid);
243 50272 : if (rc != 0) {
244 0 : goto failure;
245 : }
246 53084 : rc = json_add_string(
247 50272 : &authentication, "mappedAccount", ui->mapped.account_name);
248 50272 : if (rc != 0) {
249 0 : goto failure;
250 : }
251 53084 : rc = json_add_string(
252 50272 : &authentication, "mappedDomain", ui->mapped.domain_name);
253 50272 : if (rc != 0) {
254 0 : goto failure;
255 : }
256 53084 : rc = json_add_string(&authentication,
257 : "netlogonComputer",
258 50272 : ui->netlogon_trust_account.computer_name);
259 50272 : if (rc != 0) {
260 0 : goto failure;
261 : }
262 53084 : rc = json_add_string(&authentication,
263 : "netlogonTrustAccount",
264 50272 : ui->netlogon_trust_account.account_name);
265 50272 : if (rc != 0) {
266 0 : goto failure;
267 : }
268 53084 : rc = json_add_flags32(
269 : &authentication, "netlogonNegotiateFlags",
270 50272 : ui->netlogon_trust_account.negotiate_flags);
271 50272 : if (rc != 0) {
272 0 : goto failure;
273 : }
274 53084 : rc = json_add_int(&authentication,
275 : "netlogonSecureChannelType",
276 50272 : ui->netlogon_trust_account.secure_channel_type);
277 50272 : if (rc != 0) {
278 0 : goto failure;
279 : }
280 53084 : rc = json_add_sid(&authentication,
281 : "netlogonTrustAccountSid",
282 50272 : ui->netlogon_trust_account.sid);
283 50272 : if (rc != 0) {
284 0 : goto failure;
285 : }
286 50272 : rc = json_add_string(
287 : &authentication, "passwordType", get_password_type(ui));
288 50272 : if (rc != 0) {
289 0 : goto failure;
290 : }
291 :
292 50272 : if (client_audit_info != NULL) {
293 494 : client_policy = json_from_audit_info(client_audit_info);
294 494 : if (json_is_invalid(&client_policy)) {
295 0 : goto failure;
296 : }
297 : }
298 :
299 50272 : rc = json_add_object(&authentication, "clientPolicyAccessCheck", &client_policy);
300 50272 : if (rc != 0) {
301 0 : goto failure;
302 : }
303 :
304 50272 : if (server_audit_info != NULL) {
305 113 : server_policy = json_from_audit_info(server_audit_info);
306 113 : if (json_is_invalid(&server_policy)) {
307 0 : goto failure;
308 : }
309 : }
310 :
311 50272 : rc = json_add_object(&authentication, "serverPolicyAccessCheck", &server_policy);
312 50272 : if (rc != 0) {
313 0 : goto failure;
314 : }
315 :
316 50272 : wrapper = json_new_object();
317 50272 : if (json_is_invalid(&wrapper)) {
318 0 : goto failure;
319 : }
320 50272 : rc = json_add_timestamp(&wrapper);
321 50272 : if (rc != 0) {
322 0 : goto failure;
323 : }
324 50272 : rc = json_add_string(&wrapper, "type", AUTH_JSON_TYPE);
325 50272 : if (rc != 0) {
326 0 : goto failure;
327 : }
328 50272 : rc = json_add_object(&wrapper, AUTH_JSON_TYPE, &authentication);
329 50272 : if (rc != 0) {
330 0 : goto failure;
331 : }
332 :
333 : /*
334 : * While not a general-purpose profiling solution this will
335 : * assist some to determine how long NTLM and KDC
336 : * authentication takes once this process can handle it. This
337 : * covers transactions elsewhere but not (eg) the delay while
338 : * this is waiting unread on the input socket.
339 : */
340 50272 : if (start_time != NULL) {
341 46830 : struct timeval current_time = timeval_current();
342 46830 : uint64_t duration = usec_time_diff(¤t_time,
343 : start_time);
344 46830 : rc = json_add_int(&authentication, "duration", duration);
345 46830 : if (rc != 0) {
346 0 : goto failure;
347 : }
348 : }
349 :
350 50272 : log_json(msg_ctx,
351 : lp_ctx,
352 : &wrapper,
353 : DBGC_AUTH_AUDIT_JSON,
354 : debug_level);
355 50272 : json_free(&wrapper);
356 50272 : return;
357 0 : failure:
358 0 : json_free(&server_policy);
359 0 : json_free(&client_policy);
360 : /*
361 : * On a failure authentication will not have been added to wrapper so it
362 : * needs to be freed to avoid a leak.
363 : *
364 : */
365 0 : json_free(&authentication);
366 0 : json_free(&wrapper);
367 0 : DBG_ERR("Failed to write authentication event JSON log message\n");
368 : }
369 :
370 : /*
371 : * Log details of a successful authorization to a service,
372 : * in a machine parsable json format
373 : *
374 : * IF removing or changing the format/meaning of a field please update the
375 : * major version number AUTHZ_MAJOR
376 : *
377 : * IF adding a new field please update the minor version number AUTHZ_MINOR
378 : *
379 : * To process the resulting log lines from the command line use jq to
380 : * parse the json.
381 : *
382 : * grep "^ {" log_file |\
383 : * jq -rc '"\(.timestamp)\t
384 : * \(.Authorization.domain)\t
385 : * \(.Authorization.account)\t
386 : * \(.Authorization.remoteAddress)"'
387 : *
388 : */
389 53278 : static void log_successful_authz_event_json(
390 : struct imessaging_context *msg_ctx,
391 : struct loadparm_context *lp_ctx,
392 : const struct tsocket_address *remote,
393 : const struct tsocket_address *local,
394 : const char *service_description,
395 : const char *auth_type,
396 : const char *transport_protection,
397 : struct auth_session_info *session_info,
398 : const struct authn_audit_info *client_audit_info,
399 : const struct authn_audit_info *server_audit_info,
400 : int debug_level)
401 : {
402 53278 : struct json_object wrapper = json_empty_object;
403 53278 : struct json_object authorization = json_empty_object;
404 53278 : struct json_object client_policy = json_null_object();
405 53278 : struct json_object server_policy = json_null_object();
406 53278 : int rc = 0;
407 :
408 53278 : authorization = json_new_object();
409 53278 : if (json_is_invalid(&authorization)) {
410 0 : goto failure;
411 : }
412 53278 : rc = json_add_version(&authorization, AUTHZ_MAJOR, AUTHZ_MINOR);
413 53278 : if (rc != 0) {
414 0 : goto failure;
415 : }
416 53278 : rc = json_add_address(&authorization, "localAddress", local);
417 53278 : if (rc != 0) {
418 0 : goto failure;
419 : }
420 53278 : rc = json_add_address(&authorization, "remoteAddress", remote);
421 53278 : if (rc != 0) {
422 0 : goto failure;
423 : }
424 53278 : rc = json_add_string(
425 : &authorization, "serviceDescription", service_description);
426 53278 : if (rc != 0) {
427 0 : goto failure;
428 : }
429 53278 : rc = json_add_string(&authorization, "authType", auth_type);
430 53278 : if (rc != 0) {
431 0 : goto failure;
432 : }
433 55062 : rc = json_add_string(
434 53278 : &authorization, "domain", session_info->info->domain_name);
435 53278 : if (rc != 0) {
436 0 : goto failure;
437 : }
438 55062 : rc = json_add_string(
439 53278 : &authorization, "account", session_info->info->account_name);
440 53278 : if (rc != 0) {
441 0 : goto failure;
442 : }
443 55062 : rc = json_add_sid(
444 53278 : &authorization, "sid", &session_info->security_token->sids[PRIMARY_USER_SID_INDEX]);
445 53278 : if (rc != 0) {
446 0 : goto failure;
447 : }
448 55062 : rc = json_add_guid(
449 53278 : &authorization, "sessionId", &session_info->unique_session_token);
450 53278 : if (rc != 0) {
451 0 : goto failure;
452 : }
453 55062 : rc = json_add_string(
454 53278 : &authorization, "logonServer", session_info->info->logon_server);
455 53278 : if (rc != 0) {
456 0 : goto failure;
457 : }
458 53278 : rc = json_add_string(
459 : &authorization, "transportProtection", transport_protection);
460 53278 : if (rc != 0) {
461 0 : goto failure;
462 : }
463 53278 : rc = json_add_flags32(&authorization, "accountFlags", session_info->info->acct_flags);
464 53278 : if (rc != 0) {
465 0 : goto failure;
466 : }
467 :
468 53278 : if (client_audit_info != NULL) {
469 0 : client_policy = json_from_audit_info(client_audit_info);
470 0 : if (json_is_invalid(&client_policy)) {
471 0 : goto failure;
472 : }
473 : }
474 :
475 53278 : rc = json_add_object(&authorization, "clientPolicyAccessCheck", &client_policy);
476 53278 : if (rc != 0) {
477 0 : goto failure;
478 : }
479 :
480 53278 : if (server_audit_info != NULL) {
481 0 : server_policy = json_from_audit_info(server_audit_info);
482 0 : if (json_is_invalid(&server_policy)) {
483 0 : goto failure;
484 : }
485 : }
486 :
487 53278 : rc = json_add_object(&authorization, "serverPolicyAccessCheck", &server_policy);
488 53278 : if (rc != 0) {
489 0 : goto failure;
490 : }
491 :
492 53278 : wrapper = json_new_object();
493 53278 : if (json_is_invalid(&wrapper)) {
494 0 : goto failure;
495 : }
496 53278 : rc = json_add_timestamp(&wrapper);
497 53278 : if (rc != 0) {
498 0 : goto failure;
499 : }
500 53278 : rc = json_add_string(&wrapper, "type", AUTHZ_JSON_TYPE);
501 53278 : if (rc != 0) {
502 0 : goto failure;
503 : }
504 53278 : rc = json_add_object(&wrapper, AUTHZ_JSON_TYPE, &authorization);
505 53278 : if (rc != 0) {
506 0 : goto failure;
507 : }
508 :
509 53278 : log_json(msg_ctx,
510 : lp_ctx,
511 : &wrapper,
512 : DBGC_AUTH_AUDIT_JSON,
513 : debug_level);
514 53278 : json_free(&wrapper);
515 53278 : return;
516 0 : failure:
517 0 : json_free(&server_policy);
518 0 : json_free(&client_policy);
519 : /*
520 : * On a failure authorization will not have been added to wrapper so it
521 : * needs to be freed to avoid a leak.
522 : *
523 : */
524 0 : json_free(&authorization);
525 0 : json_free(&wrapper);
526 0 : DBG_ERR("Unable to log Authentication event JSON audit message\n");
527 : }
528 :
529 : /*
530 : * Log details of an authorization to a service, in a machine parsable json
531 : * format
532 : *
533 : * IF removing or changing the format/meaning of a field please update the
534 : * major version number KDC_AUTHZ_MAJOR
535 : *
536 : * IF adding a new field please update the minor version number KDC_AUTHZ_MINOR
537 : *
538 : * To process the resulting log lines from the command line use jq to
539 : * parse the json.
540 : *
541 : * grep "^ {" log_file |\
542 : * jq -rc '"\(.timestamp)\t
543 : * \(."KDC Authorization".domain)\t
544 : * \(."KDC Authorization".account)\t
545 : * \(."KDC Authorization".remoteAddress)"'
546 : *
547 : */
548 33021 : static void log_authz_event_json(
549 : struct imessaging_context *msg_ctx,
550 : struct loadparm_context *lp_ctx,
551 : const struct tsocket_address *remote,
552 : const struct tsocket_address *local,
553 : const struct authn_audit_info *server_audit_info,
554 : const char *service_description,
555 : const char *auth_type,
556 : const char *domain_name,
557 : const char *account_name,
558 : const struct dom_sid *sid,
559 : const char *logon_server,
560 : const struct timeval authtime,
561 : NTSTATUS status,
562 : int debug_level)
563 : {
564 33021 : struct json_object wrapper = json_empty_object;
565 33021 : struct json_object authorization = json_empty_object;
566 33021 : struct json_object server_policy = json_null_object();
567 33021 : int rc = 0;
568 :
569 33021 : authorization = json_new_object();
570 33021 : if (json_is_invalid(&authorization)) {
571 0 : goto failure;
572 : }
573 33021 : rc = json_add_version(&authorization, KDC_AUTHZ_MAJOR, KDC_AUTHZ_MINOR);
574 33021 : if (rc != 0) {
575 0 : goto failure;
576 : }
577 33021 : rc = json_add_string(&authorization, "status", nt_errstr(status));
578 33021 : if (rc != 0) {
579 0 : goto failure;
580 : }
581 33021 : rc = json_add_address(&authorization, "localAddress", local);
582 33021 : if (rc != 0) {
583 0 : goto failure;
584 : }
585 33021 : rc = json_add_address(&authorization, "remoteAddress", remote);
586 33021 : if (rc != 0) {
587 0 : goto failure;
588 : }
589 33021 : rc = json_add_string(
590 : &authorization, "serviceDescription", service_description);
591 33021 : if (rc != 0) {
592 0 : goto failure;
593 : }
594 33021 : rc = json_add_string(&authorization, "authType", auth_type);
595 33021 : if (rc != 0) {
596 0 : goto failure;
597 : }
598 33021 : rc = json_add_string(&authorization, "domain", domain_name);
599 33021 : if (rc != 0) {
600 0 : goto failure;
601 : }
602 33021 : rc = json_add_string(&authorization, "account", account_name);
603 33021 : if (rc != 0) {
604 0 : goto failure;
605 : }
606 33021 : rc = json_add_sid(&authorization, "sid", sid);
607 33021 : if (rc != 0) {
608 0 : goto failure;
609 : }
610 33021 : rc = json_add_string(&authorization, "logonServer", logon_server);
611 33021 : if (rc != 0) {
612 0 : goto failure;
613 : }
614 33021 : rc = json_add_time(&authorization, "authTime", authtime);
615 33021 : if (rc != 0) {
616 0 : goto failure;
617 : }
618 :
619 33021 : if (server_audit_info != NULL) {
620 161 : server_policy = json_from_audit_info(server_audit_info);
621 161 : if (json_is_invalid(&server_policy)) {
622 0 : goto failure;
623 : }
624 : }
625 :
626 33021 : rc = json_add_object(&authorization, "serverPolicyAccessCheck", &server_policy);
627 33021 : if (rc != 0) {
628 0 : goto failure;
629 : }
630 :
631 33021 : wrapper = json_new_object();
632 33021 : if (json_is_invalid(&wrapper)) {
633 0 : goto failure;
634 : }
635 33021 : rc = json_add_timestamp(&wrapper);
636 33021 : if (rc != 0) {
637 0 : goto failure;
638 : }
639 33021 : rc = json_add_string(&wrapper, "type", KDC_AUTHZ_JSON_TYPE);
640 33021 : if (rc != 0) {
641 0 : goto failure;
642 : }
643 33021 : rc = json_add_object(&wrapper, KDC_AUTHZ_JSON_TYPE, &authorization);
644 33021 : if (rc != 0) {
645 0 : goto failure;
646 : }
647 :
648 33021 : log_json(msg_ctx,
649 : lp_ctx,
650 : &wrapper,
651 : DBGC_AUTH_AUDIT_JSON,
652 : debug_level);
653 33021 : json_free(&wrapper);
654 33021 : return;
655 0 : failure:
656 0 : json_free(&server_policy);
657 : /*
658 : * On a failure authorization will not have been added to wrapper so it
659 : * needs to be freed to avoid a leak.
660 : */
661 0 : json_free(&authorization);
662 0 : json_free(&wrapper);
663 0 : DBG_ERR("Unable to log KDC Authorization event JSON audit message\n");
664 : }
665 :
666 : #else
667 :
668 0 : static void log_no_json(struct imessaging_context *msg_ctx,
669 : struct loadparm_context *lp_ctx)
670 : {
671 0 : if (msg_ctx && lp_ctx && lpcfg_auth_event_notification(lp_ctx)) {
672 : static bool auth_event_logged = false;
673 0 : if (auth_event_logged == false) {
674 0 : auth_event_logged = true;
675 0 : DBG_ERR("auth event notification = true but Samba was "
676 : "not compiled with jansson\n");
677 : }
678 : } else {
679 : static bool json_logged = false;
680 0 : if (json_logged == false) {
681 0 : json_logged = true;
682 0 : DBG_NOTICE("JSON auth logs not available unless "
683 : "compiled with jansson\n");
684 : }
685 : }
686 0 : }
687 :
688 0 : static void log_authentication_event_json(
689 : struct imessaging_context *msg_ctx,
690 : struct loadparm_context *lp_ctx,
691 : const struct timeval *start_time,
692 : const struct auth_usersupplied_info *ui,
693 : NTSTATUS status,
694 : const char *domain_name,
695 : const char *account_name,
696 : struct dom_sid *sid,
697 : const struct authn_audit_info *client_audit_info,
698 : const struct authn_audit_info *server_audit_info,
699 : enum event_id_type event_id,
700 : int debug_level)
701 : {
702 0 : log_no_json(msg_ctx, lp_ctx);
703 0 : }
704 :
705 0 : static void log_successful_authz_event_json(
706 : struct imessaging_context *msg_ctx,
707 : struct loadparm_context *lp_ctx,
708 : const struct tsocket_address *remote,
709 : const struct tsocket_address *local,
710 : const char *service_description,
711 : const char *auth_type,
712 : const char *transport_protection,
713 : struct auth_session_info *session_info,
714 : const struct authn_audit_info *client_audit_info,
715 : const struct authn_audit_info *server_audit_info,
716 : int debug_level)
717 : {
718 0 : log_no_json(msg_ctx, lp_ctx);
719 0 : }
720 :
721 0 : static void log_authz_event_json(
722 : struct imessaging_context *msg_ctx,
723 : struct loadparm_context *lp_ctx,
724 : const struct tsocket_address *remote,
725 : const struct tsocket_address *local,
726 : const struct authn_audit_info *server_audit_info,
727 : const char *service_description,
728 : const char *auth_type,
729 : const char *domain_name,
730 : const char *account_name,
731 : const struct dom_sid *sid,
732 : const char *logon_server,
733 : const struct timeval authtime,
734 : NTSTATUS status,
735 : int debug_level)
736 : {
737 0 : log_no_json(msg_ctx, lp_ctx);
738 0 : }
739 :
740 : #endif
741 :
742 : /*
743 : * Determine the type of the password supplied for the
744 : * authorisation attempt.
745 : *
746 : */
747 50272 : static const char* get_password_type(const struct auth_usersupplied_info *ui)
748 : {
749 :
750 50272 : const char *password_type = NULL;
751 :
752 50272 : if (ui->password_type != NULL) {
753 22387 : password_type = ui->password_type;
754 26715 : } else if (ui->auth_description != NULL &&
755 25881 : strncmp("ServerAuthenticate", ui->auth_description, 18) == 0)
756 : {
757 2019 : if (ui->netlogon_trust_account.negotiate_flags
758 2019 : & NETLOGON_NEG_SUPPORTS_AES) {
759 1394 : password_type = "HMAC-SHA256";
760 475 : } else if (ui->netlogon_trust_account.negotiate_flags
761 475 : & NETLOGON_NEG_STRONG_KEYS) {
762 134 : password_type = "HMAC-MD5";
763 : } else {
764 317 : password_type = "DES";
765 : }
766 24696 : } else if (ui->password_state == AUTH_PASSWORD_RESPONSE &&
767 23149 : (ui->logon_parameters & MSV1_0_ALLOW_MSVCHAPV2) &&
768 7 : ui->password.response.nt.length == 24) {
769 7 : password_type = "MSCHAPv2";
770 24689 : } else if ((ui->logon_parameters & MSV1_0_CLEARTEXT_PASSWORD_SUPPLIED)
771 24367 : || (ui->password_state == AUTH_PASSWORD_PLAIN)) {
772 322 : password_type = "Plaintext";
773 24367 : } else if (ui->password_state == AUTH_PASSWORD_HASH) {
774 540 : password_type = "Supplied-NT-Hash";
775 23827 : } else if (ui->password_state == AUTH_PASSWORD_RESPONSE
776 23134 : && ui->password.response.nt.length > 24) {
777 16708 : password_type = "NTLMv2";
778 5709 : } else if (ui->password_state == AUTH_PASSWORD_RESPONSE
779 5016 : && ui->password.response.nt.length == 24) {
780 3006 : password_type = "NTLMv1";
781 2703 : } else if (ui->password_state == AUTH_PASSWORD_RESPONSE
782 2010 : && ui->password.response.lanman.length == 24) {
783 900 : password_type = "LANMan";
784 1803 : } else if (ui->password_state == AUTH_PASSWORD_RESPONSE
785 1110 : && ui->password.response.nt.length == 0
786 870 : && ui->password.response.lanman.length == 0) {
787 666 : password_type = "No-Password";
788 : }
789 50272 : return password_type;
790 : }
791 :
792 : /*
793 : * Write a human readable authentication log entry.
794 : *
795 : */
796 0 : static void log_authentication_event_human_readable(
797 : const struct auth_usersupplied_info *ui,
798 : NTSTATUS status,
799 : const char *domain_name,
800 : const char *account_name,
801 : struct dom_sid *sid,
802 : int debug_level)
803 : {
804 0 : TALLOC_CTX *frame = NULL;
805 :
806 0 : const char *ts = NULL; /* formatted current time */
807 0 : char *remote = NULL; /* formatted remote host */
808 0 : char *local = NULL; /* formatted local host */
809 0 : char *nl = NULL; /* NETLOGON details if present */
810 0 : char *trust_computer_name = NULL;
811 0 : char *trust_account_name = NULL;
812 0 : char *logon_line = NULL;
813 0 : const char *password_type = NULL;
814 0 : const char *clientDomain = ui->orig_client.domain_name ?
815 0 : ui->orig_client.domain_name :
816 : ui->client.domain_name;
817 0 : const char *clientAccount = ui->orig_client.account_name ?
818 0 : ui->orig_client.account_name :
819 : ui->client.account_name;
820 :
821 0 : frame = talloc_stackframe();
822 :
823 0 : password_type = get_password_type(ui);
824 : /* Get the current time */
825 0 : ts = audit_get_timestamp(frame);
826 :
827 : /* Only log the NETLOGON details if they are present */
828 0 : if (ui->netlogon_trust_account.computer_name ||
829 0 : ui->netlogon_trust_account.account_name) {
830 0 : trust_computer_name = log_escape(frame,
831 0 : ui->netlogon_trust_account.computer_name);
832 0 : trust_account_name = log_escape(frame,
833 0 : ui->netlogon_trust_account.account_name);
834 0 : nl = talloc_asprintf(frame,
835 : " NETLOGON computer [%s] trust account [%s]",
836 : trust_computer_name, trust_account_name);
837 : }
838 :
839 0 : remote = tsocket_address_string(ui->remote_host, frame);
840 0 : local = tsocket_address_string(ui->local_host, frame);
841 :
842 0 : if (NT_STATUS_IS_OK(status)) {
843 0 : struct dom_sid_buf sid_buf;
844 :
845 0 : logon_line = talloc_asprintf(frame,
846 : " became [%s]\\[%s] [%s].",
847 : log_escape(frame, domain_name),
848 : log_escape(frame, account_name),
849 : dom_sid_str_buf(sid, &sid_buf));
850 : } else {
851 0 : logon_line = talloc_asprintf(
852 : frame,
853 : " mapped to [%s]\\[%s].",
854 0 : log_escape(frame, ui->mapped.domain_name),
855 0 : log_escape(frame, ui->mapped.account_name));
856 : }
857 :
858 0 : DEBUGC(DBGC_AUTH_AUDIT, debug_level,
859 : ("Auth: [%s,%s] user [%s]\\[%s]"
860 : " at [%s] with [%s] status [%s]"
861 : " workstation [%s] remote host [%s]"
862 : "%s local host [%s]"
863 : " %s\n",
864 : ui->service_description,
865 : ui->auth_description,
866 : log_escape(frame, clientDomain),
867 : log_escape(frame, clientAccount),
868 : ts,
869 : password_type,
870 : nt_errstr(status),
871 : log_escape(frame, ui->workstation_name),
872 : remote,
873 : logon_line,
874 : local,
875 : nl ? nl : ""
876 : ));
877 :
878 0 : talloc_free(frame);
879 0 : }
880 :
881 : /*
882 : * Log details of an authentication attempt.
883 : * Successful and unsuccessful attempts are logged.
884 : *
885 : * NOTE: msg_ctx and lp_ctx is optional, but when supplied allows streaming the
886 : * authentication events over the message bus.
887 : */
888 89356 : void log_authentication_event(
889 : struct imessaging_context *msg_ctx,
890 : struct loadparm_context *lp_ctx,
891 : const struct timeval *start_time,
892 : const struct auth_usersupplied_info *ui,
893 : NTSTATUS status,
894 : const char *domain_name,
895 : const char *account_name,
896 : struct dom_sid *sid,
897 : const struct authn_audit_info *client_audit_info,
898 : const struct authn_audit_info *server_audit_info)
899 : {
900 : /* set the log level */
901 89356 : int debug_level = AUTH_FAILURE_LEVEL;
902 89356 : enum event_id_type event_id = EVT_ID_UNSUCCESSFUL_LOGON;
903 :
904 89356 : if (NT_STATUS_IS_OK(status)) {
905 65393 : debug_level = AUTH_SUCCESS_LEVEL;
906 65393 : event_id = EVT_ID_SUCCESSFUL_LOGON;
907 65393 : if (dom_sid_equal(sid, &global_sid_Anonymous)) {
908 592 : debug_level = AUTH_ANONYMOUS_LEVEL;
909 : }
910 : }
911 :
912 89356 : if (CHECK_DEBUGLVLC(DBGC_AUTH_AUDIT, debug_level)) {
913 0 : log_authentication_event_human_readable(ui,
914 : status,
915 : domain_name,
916 : account_name,
917 : sid,
918 : debug_level);
919 : }
920 89356 : if (CHECK_DEBUGLVLC(DBGC_AUTH_AUDIT_JSON, debug_level) ||
921 66499 : (msg_ctx && lp_ctx && lpcfg_auth_event_notification(lp_ctx))) {
922 50272 : log_authentication_event_json(msg_ctx,
923 : lp_ctx,
924 : start_time,
925 : ui,
926 : status,
927 : domain_name,
928 : account_name,
929 : sid,
930 : client_audit_info,
931 : server_audit_info,
932 : event_id,
933 : debug_level);
934 : }
935 89356 : }
936 :
937 :
938 :
939 : /*
940 : * Log details of a successful authorization to a service,
941 : * in a human readable format.
942 : *
943 : */
944 0 : static void log_successful_authz_event_human_readable(
945 : const struct tsocket_address *remote,
946 : const struct tsocket_address *local,
947 : const char *service_description,
948 : const char *auth_type,
949 : struct auth_session_info *session_info,
950 : int debug_level)
951 : {
952 0 : TALLOC_CTX *frame = NULL;
953 :
954 0 : const char *ts = NULL; /* formatted current time */
955 0 : char *remote_str = NULL; /* formatted remote host */
956 0 : char *local_str = NULL; /* formatted local host */
957 0 : struct dom_sid_buf sid_buf;
958 :
959 0 : frame = talloc_stackframe();
960 :
961 : /* Get the current time */
962 0 : ts = audit_get_timestamp(frame);
963 :
964 0 : remote_str = tsocket_address_string(remote, frame);
965 0 : local_str = tsocket_address_string(local, frame);
966 :
967 0 : DEBUGC(DBGC_AUTH_AUDIT, debug_level,
968 : ("Successful AuthZ: [%s,%s] user [%s]\\[%s] [%s]"
969 : " at [%s]"
970 : " Remote host [%s]"
971 : " local host [%s]\n",
972 : service_description,
973 : auth_type,
974 : log_escape(frame, session_info->info->domain_name),
975 : log_escape(frame, session_info->info->account_name),
976 : dom_sid_str_buf(&session_info->security_token->sids[PRIMARY_USER_SID_INDEX],
977 : &sid_buf),
978 : ts,
979 : remote_str,
980 : local_str));
981 :
982 0 : talloc_free(frame);
983 0 : }
984 :
985 : /*
986 : * Log details of a successful authorization to a service.
987 : *
988 : * Only successful authorizations are logged. For clarity:
989 : * - NTLM bad passwords will be recorded by log_authentication_event
990 : * - Kerberos decrypt failures need to be logged in gensec_gssapi et al
991 : *
992 : * The service may later refuse authorization due to an ACL.
993 : *
994 : * NOTE: msg_ctx and lp_ctx is optional, but when supplied allows streaming the
995 : * authentication events over the message bus.
996 : */
997 116658 : void log_successful_authz_event(
998 : struct imessaging_context *msg_ctx,
999 : struct loadparm_context *lp_ctx,
1000 : const struct tsocket_address *remote,
1001 : const struct tsocket_address *local,
1002 : const char *service_description,
1003 : const char *auth_type,
1004 : const char *transport_protection,
1005 : struct auth_session_info *session_info,
1006 : const struct authn_audit_info *client_audit_info,
1007 : const struct authn_audit_info *server_audit_info)
1008 : {
1009 116658 : int debug_level = AUTHZ_SUCCESS_LEVEL;
1010 :
1011 : /* set the log level */
1012 116658 : if (security_token_is_anonymous(session_info->security_token)) {
1013 11162 : debug_level = AUTH_ANONYMOUS_LEVEL;
1014 : }
1015 :
1016 116658 : if (CHECK_DEBUGLVLC(DBGC_AUTH_AUDIT, debug_level)) {
1017 0 : log_successful_authz_event_human_readable(remote,
1018 : local,
1019 : service_description,
1020 : auth_type,
1021 : session_info,
1022 : debug_level);
1023 : }
1024 116658 : if (CHECK_DEBUGLVLC(DBGC_AUTH_AUDIT_JSON, debug_level) ||
1025 75188 : (msg_ctx && lp_ctx && lpcfg_auth_event_notification(lp_ctx))) {
1026 53278 : log_successful_authz_event_json(msg_ctx, lp_ctx,
1027 : remote,
1028 : local,
1029 : service_description,
1030 : auth_type,
1031 : transport_protection,
1032 : session_info,
1033 : client_audit_info,
1034 : server_audit_info,
1035 : debug_level);
1036 : }
1037 116658 : }
1038 :
1039 : /*
1040 : * Log details of an authorization to a service.
1041 : *
1042 : * NOTE: msg_ctx and lp_ctx are optional, but when supplied, allow streaming the
1043 : * authorization events over the message bus.
1044 : */
1045 52529 : void log_authz_event(
1046 : struct imessaging_context *msg_ctx,
1047 : struct loadparm_context *lp_ctx,
1048 : const struct tsocket_address *remote,
1049 : const struct tsocket_address *local,
1050 : const struct authn_audit_info *server_audit_info,
1051 : const char *service_description,
1052 : const char *auth_type,
1053 : const char *domain_name,
1054 : const char *account_name,
1055 : const struct dom_sid *sid,
1056 : const char *logon_server,
1057 : const struct timeval authtime,
1058 : NTSTATUS status)
1059 : {
1060 : /* set the log level */
1061 52529 : int debug_level = KDC_AUTHZ_FAILURE_LEVEL;
1062 :
1063 52529 : if (NT_STATUS_IS_OK(status)) {
1064 49245 : debug_level = KDC_AUTHZ_SUCCESS_LEVEL;
1065 : }
1066 :
1067 52529 : if (CHECK_DEBUGLVLC(DBGC_AUTH_AUDIT_JSON, debug_level) ||
1068 52529 : (msg_ctx && lp_ctx && lpcfg_auth_event_notification(lp_ctx))) {
1069 33021 : log_authz_event_json(msg_ctx, lp_ctx,
1070 : remote,
1071 : local,
1072 : server_audit_info,
1073 : service_description,
1074 : auth_type,
1075 : domain_name,
1076 : account_name,
1077 : sid,
1078 : logon_server,
1079 : authtime,
1080 : status,
1081 : debug_level);
1082 : }
1083 52529 : }
|