libnet: Fix Coverity ID 1634803 Dereference after null check
[samba4-gss.git] / auth / auth_log.c
blob9a110fd0b4864ae2f97fce74b7e4940f2d09d4e5
1 /*
3 Authentication and authorization logging
5 Copyright (C) Andrew Bartlett <abartlet@samba.org> 2017
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.
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.
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/>.
22 * Debug log levels for authentication logging (these both map to
23 * LOG_NOTICE in syslog)
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
31 /* 5 is used for both authentication and authorization */
32 #define AUTH_ANONYMOUS_LEVEL 5
33 #define AUTHZ_ANONYMOUS_LEVEL 5
35 #define AUTHZ_JSON_TYPE "Authorization"
36 #define AUTH_JSON_TYPE "Authentication"
37 #define KDC_AUTHZ_JSON_TYPE "KDC Authorization"
40 * JSON message version numbers
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.
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
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"
69 * Determine the type of the password supplied for the
70 * authorisation attempt.
73 static const char* get_password_type(const struct auth_usersupplied_info *ui);
75 #ifdef HAVE_JANSSON
77 #include <jansson.h>
78 #include "system/time.h"
81 * Write the json object to the debug logs.
84 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)
90 audit_log_json(object, debug_class, debug_level);
91 if (msg_ctx && lp_ctx && lpcfg_auth_event_notification(lp_ctx)) {
92 audit_message_send(msg_ctx,
93 AUTH_EVENT_NAME,
94 MSG_AUTH_LOG,
95 object);
100 * Determine the Windows logon type for the current authorisation attempt.
102 * Currently Samba only supports
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.
112 static enum event_logon_type get_logon_type(
113 const struct auth_usersupplied_info *ui)
115 if ((ui->logon_parameters & MSV1_0_CLEARTEXT_PASSWORD_SUPPLIED)
116 || (ui->password_state == AUTH_PASSWORD_PLAIN)) {
117 return EVT_LOGON_NETWORK_CLEAR_TEXT;
118 } else if (ui->flags & USER_INFO_INTERACTIVE_LOGON) {
119 return EVT_LOGON_INTERACTIVE;
121 return EVT_LOGON_NETWORK;
125 * Write a machine parsable json formatted authentication log entry.
127 * IF removing or changing the format/meaning of a field please update the
128 * major version number AUTH_MAJOR
130 * IF adding a new field please update the minor version number AUTH_MINOR
132 * To process the resulting log lines from the command line use jq to
133 * parse the json.
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)"'
143 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)
157 struct json_object wrapper = json_empty_object;
158 struct json_object authentication = json_empty_object;
159 struct json_object client_policy = json_null_object();
160 struct json_object server_policy = json_null_object();
161 char logon_id[19];
162 int rc = 0;
163 const char *clientDomain = ui->orig_client.domain_name ?
164 ui->orig_client.domain_name :
165 ui->client.domain_name;
166 const char *clientAccount = ui->orig_client.account_name ?
167 ui->orig_client.account_name :
168 ui->client.account_name;
170 authentication = json_new_object();
171 if (json_is_invalid(&authentication)) {
172 goto failure;
174 rc = json_add_version(&authentication, AUTH_MAJOR, AUTH_MINOR);
175 if (rc != 0) {
176 goto failure;
178 rc = json_add_int(&authentication,
179 "eventId",
180 event_id);
181 if (rc != 0) {
182 goto failure;
184 snprintf(logon_id,
185 sizeof( logon_id),
186 "%"PRIx64"",
187 ui->logon_id);
188 rc = json_add_string(&authentication, "logonId", logon_id);
189 if (rc != 0) {
190 goto failure;
192 rc = json_add_int(&authentication, "logonType", get_logon_type(ui));
193 if (rc != 0) {
194 goto failure;
196 rc = json_add_string(&authentication, "status", nt_errstr(status));
197 if (rc != 0) {
198 goto failure;
200 rc = json_add_address(&authentication, "localAddress", ui->local_host);
201 if (rc != 0) {
202 goto failure;
204 rc =
205 json_add_address(&authentication, "remoteAddress", ui->remote_host);
206 if (rc != 0) {
207 goto failure;
209 rc = json_add_string(
210 &authentication, "serviceDescription", ui->service_description);
211 if (rc != 0) {
212 goto failure;
214 rc = json_add_string(
215 &authentication, "authDescription", ui->auth_description);
216 if (rc != 0) {
217 goto failure;
219 rc = json_add_string(
220 &authentication, "clientDomain", clientDomain);
221 if (rc != 0) {
222 goto failure;
224 rc = json_add_string(
225 &authentication, "clientAccount", clientAccount);
226 if (rc != 0) {
227 goto failure;
229 rc = json_add_string(
230 &authentication, "workstation", ui->workstation_name);
231 if (rc != 0) {
232 goto failure;
234 rc = json_add_string(&authentication, "becameAccount", account_name);
235 if (rc != 0) {
236 goto failure;
238 rc = json_add_string(&authentication, "becameDomain", domain_name);
239 if (rc != 0) {
240 goto failure;
242 rc = json_add_sid(&authentication, "becameSid", sid);
243 if (rc != 0) {
244 goto failure;
246 rc = json_add_string(
247 &authentication, "mappedAccount", ui->mapped.account_name);
248 if (rc != 0) {
249 goto failure;
251 rc = json_add_string(
252 &authentication, "mappedDomain", ui->mapped.domain_name);
253 if (rc != 0) {
254 goto failure;
256 rc = json_add_string(&authentication,
257 "netlogonComputer",
258 ui->netlogon_trust_account.computer_name);
259 if (rc != 0) {
260 goto failure;
262 rc = json_add_string(&authentication,
263 "netlogonTrustAccount",
264 ui->netlogon_trust_account.account_name);
265 if (rc != 0) {
266 goto failure;
268 rc = json_add_flags32(
269 &authentication, "netlogonNegotiateFlags",
270 ui->netlogon_trust_account.negotiate_flags);
271 if (rc != 0) {
272 goto failure;
274 rc = json_add_int(&authentication,
275 "netlogonSecureChannelType",
276 ui->netlogon_trust_account.secure_channel_type);
277 if (rc != 0) {
278 goto failure;
280 rc = json_add_sid(&authentication,
281 "netlogonTrustAccountSid",
282 ui->netlogon_trust_account.sid);
283 if (rc != 0) {
284 goto failure;
286 rc = json_add_string(
287 &authentication, "passwordType", get_password_type(ui));
288 if (rc != 0) {
289 goto failure;
292 if (client_audit_info != NULL) {
293 client_policy = json_from_audit_info(client_audit_info);
294 if (json_is_invalid(&client_policy)) {
295 goto failure;
299 rc = json_add_object(&authentication, "clientPolicyAccessCheck", &client_policy);
300 if (rc != 0) {
301 goto failure;
304 if (server_audit_info != NULL) {
305 server_policy = json_from_audit_info(server_audit_info);
306 if (json_is_invalid(&server_policy)) {
307 goto failure;
311 rc = json_add_object(&authentication, "serverPolicyAccessCheck", &server_policy);
312 if (rc != 0) {
313 goto failure;
316 wrapper = json_new_object();
317 if (json_is_invalid(&wrapper)) {
318 goto failure;
320 rc = json_add_timestamp(&wrapper);
321 if (rc != 0) {
322 goto failure;
324 rc = json_add_string(&wrapper, "type", AUTH_JSON_TYPE);
325 if (rc != 0) {
326 goto failure;
328 rc = json_add_object(&wrapper, AUTH_JSON_TYPE, &authentication);
329 if (rc != 0) {
330 goto failure;
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.
340 if (start_time != NULL) {
341 struct timeval current_time = timeval_current();
342 uint64_t duration = usec_time_diff(&current_time,
343 start_time);
344 rc = json_add_int(&authentication, "duration", duration);
345 if (rc != 0) {
346 goto failure;
350 log_json(msg_ctx,
351 lp_ctx,
352 &wrapper,
353 DBGC_AUTH_AUDIT_JSON,
354 debug_level);
355 json_free(&wrapper);
356 return;
357 failure:
358 json_free(&server_policy);
359 json_free(&client_policy);
361 * On a failure authentication will not have been added to wrapper so it
362 * needs to be freed to avoid a leak.
365 json_free(&authentication);
366 json_free(&wrapper);
367 DBG_ERR("Failed to write authentication event JSON log message\n");
371 * Log details of a successful authorization to a service,
372 * in a machine parsable json format
374 * IF removing or changing the format/meaning of a field please update the
375 * major version number AUTHZ_MAJOR
377 * IF adding a new field please update the minor version number AUTHZ_MINOR
379 * To process the resulting log lines from the command line use jq to
380 * parse the json.
382 * grep "^ {" log_file |\
383 * jq -rc '"\(.timestamp)\t
384 * \(.Authorization.domain)\t
385 * \(.Authorization.account)\t
386 * \(.Authorization.remoteAddress)"'
389 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)
402 struct json_object wrapper = json_empty_object;
403 struct json_object authorization = json_empty_object;
404 struct json_object client_policy = json_null_object();
405 struct json_object server_policy = json_null_object();
406 int rc = 0;
408 authorization = json_new_object();
409 if (json_is_invalid(&authorization)) {
410 goto failure;
412 rc = json_add_version(&authorization, AUTHZ_MAJOR, AUTHZ_MINOR);
413 if (rc != 0) {
414 goto failure;
416 rc = json_add_address(&authorization, "localAddress", local);
417 if (rc != 0) {
418 goto failure;
420 rc = json_add_address(&authorization, "remoteAddress", remote);
421 if (rc != 0) {
422 goto failure;
424 rc = json_add_string(
425 &authorization, "serviceDescription", service_description);
426 if (rc != 0) {
427 goto failure;
429 rc = json_add_string(&authorization, "authType", auth_type);
430 if (rc != 0) {
431 goto failure;
433 rc = json_add_string(
434 &authorization, "domain", session_info->info->domain_name);
435 if (rc != 0) {
436 goto failure;
438 rc = json_add_string(
439 &authorization, "account", session_info->info->account_name);
440 if (rc != 0) {
441 goto failure;
443 rc = json_add_sid(
444 &authorization, "sid", &session_info->security_token->sids[PRIMARY_USER_SID_INDEX]);
445 if (rc != 0) {
446 goto failure;
448 rc = json_add_guid(
449 &authorization, "sessionId", &session_info->unique_session_token);
450 if (rc != 0) {
451 goto failure;
453 rc = json_add_string(
454 &authorization, "logonServer", session_info->info->logon_server);
455 if (rc != 0) {
456 goto failure;
458 rc = json_add_string(
459 &authorization, "transportProtection", transport_protection);
460 if (rc != 0) {
461 goto failure;
463 rc = json_add_flags32(&authorization, "accountFlags", session_info->info->acct_flags);
464 if (rc != 0) {
465 goto failure;
468 if (client_audit_info != NULL) {
469 client_policy = json_from_audit_info(client_audit_info);
470 if (json_is_invalid(&client_policy)) {
471 goto failure;
475 rc = json_add_object(&authorization, "clientPolicyAccessCheck", &client_policy);
476 if (rc != 0) {
477 goto failure;
480 if (server_audit_info != NULL) {
481 server_policy = json_from_audit_info(server_audit_info);
482 if (json_is_invalid(&server_policy)) {
483 goto failure;
487 rc = json_add_object(&authorization, "serverPolicyAccessCheck", &server_policy);
488 if (rc != 0) {
489 goto failure;
492 wrapper = json_new_object();
493 if (json_is_invalid(&wrapper)) {
494 goto failure;
496 rc = json_add_timestamp(&wrapper);
497 if (rc != 0) {
498 goto failure;
500 rc = json_add_string(&wrapper, "type", AUTHZ_JSON_TYPE);
501 if (rc != 0) {
502 goto failure;
504 rc = json_add_object(&wrapper, AUTHZ_JSON_TYPE, &authorization);
505 if (rc != 0) {
506 goto failure;
509 log_json(msg_ctx,
510 lp_ctx,
511 &wrapper,
512 DBGC_AUTH_AUDIT_JSON,
513 debug_level);
514 json_free(&wrapper);
515 return;
516 failure:
517 json_free(&server_policy);
518 json_free(&client_policy);
520 * On a failure authorization will not have been added to wrapper so it
521 * needs to be freed to avoid a leak.
524 json_free(&authorization);
525 json_free(&wrapper);
526 DBG_ERR("Unable to log Authentication event JSON audit message\n");
530 * Log details of an authorization to a service, in a machine parsable json
531 * format
533 * IF removing or changing the format/meaning of a field please update the
534 * major version number KDC_AUTHZ_MAJOR
536 * IF adding a new field please update the minor version number KDC_AUTHZ_MINOR
538 * To process the resulting log lines from the command line use jq to
539 * parse the json.
541 * grep "^ {" log_file |\
542 * jq -rc '"\(.timestamp)\t
543 * \(."KDC Authorization".domain)\t
544 * \(."KDC Authorization".account)\t
545 * \(."KDC Authorization".remoteAddress)"'
548 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)
564 struct json_object wrapper = json_empty_object;
565 struct json_object authorization = json_empty_object;
566 struct json_object server_policy = json_null_object();
567 int rc = 0;
569 authorization = json_new_object();
570 if (json_is_invalid(&authorization)) {
571 goto failure;
573 rc = json_add_version(&authorization, KDC_AUTHZ_MAJOR, KDC_AUTHZ_MINOR);
574 if (rc != 0) {
575 goto failure;
577 rc = json_add_string(&authorization, "status", nt_errstr(status));
578 if (rc != 0) {
579 goto failure;
581 rc = json_add_address(&authorization, "localAddress", local);
582 if (rc != 0) {
583 goto failure;
585 rc = json_add_address(&authorization, "remoteAddress", remote);
586 if (rc != 0) {
587 goto failure;
589 rc = json_add_string(
590 &authorization, "serviceDescription", service_description);
591 if (rc != 0) {
592 goto failure;
594 rc = json_add_string(&authorization, "authType", auth_type);
595 if (rc != 0) {
596 goto failure;
598 rc = json_add_string(&authorization, "domain", domain_name);
599 if (rc != 0) {
600 goto failure;
602 rc = json_add_string(&authorization, "account", account_name);
603 if (rc != 0) {
604 goto failure;
606 rc = json_add_sid(&authorization, "sid", sid);
607 if (rc != 0) {
608 goto failure;
610 rc = json_add_string(&authorization, "logonServer", logon_server);
611 if (rc != 0) {
612 goto failure;
614 rc = json_add_time(&authorization, "authTime", authtime);
615 if (rc != 0) {
616 goto failure;
619 if (server_audit_info != NULL) {
620 server_policy = json_from_audit_info(server_audit_info);
621 if (json_is_invalid(&server_policy)) {
622 goto failure;
626 rc = json_add_object(&authorization, "serverPolicyAccessCheck", &server_policy);
627 if (rc != 0) {
628 goto failure;
631 wrapper = json_new_object();
632 if (json_is_invalid(&wrapper)) {
633 goto failure;
635 rc = json_add_timestamp(&wrapper);
636 if (rc != 0) {
637 goto failure;
639 rc = json_add_string(&wrapper, "type", KDC_AUTHZ_JSON_TYPE);
640 if (rc != 0) {
641 goto failure;
643 rc = json_add_object(&wrapper, KDC_AUTHZ_JSON_TYPE, &authorization);
644 if (rc != 0) {
645 goto failure;
648 log_json(msg_ctx,
649 lp_ctx,
650 &wrapper,
651 DBGC_AUTH_AUDIT_JSON,
652 debug_level);
653 json_free(&wrapper);
654 return;
655 failure:
656 json_free(&server_policy);
658 * On a failure authorization will not have been added to wrapper so it
659 * needs to be freed to avoid a leak.
661 json_free(&authorization);
662 json_free(&wrapper);
663 DBG_ERR("Unable to log KDC Authorization event JSON audit message\n");
666 #else
668 static void log_no_json(struct imessaging_context *msg_ctx,
669 struct loadparm_context *lp_ctx)
671 if (msg_ctx && lp_ctx && lpcfg_auth_event_notification(lp_ctx)) {
672 static bool auth_event_logged = false;
673 if (auth_event_logged == false) {
674 auth_event_logged = true;
675 DBG_ERR("auth event notification = true but Samba was "
676 "not compiled with jansson\n");
678 } else {
679 static bool json_logged = false;
680 if (json_logged == false) {
681 json_logged = true;
682 DBG_NOTICE("JSON auth logs not available unless "
683 "compiled with jansson\n");
688 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)
702 log_no_json(msg_ctx, lp_ctx);
705 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)
718 log_no_json(msg_ctx, lp_ctx);
721 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)
737 log_no_json(msg_ctx, lp_ctx);
740 #endif
743 * Determine the type of the password supplied for the
744 * authorisation attempt.
747 static const char* get_password_type(const struct auth_usersupplied_info *ui)
750 const char *password_type = NULL;
752 if (ui->password_type != NULL) {
753 password_type = ui->password_type;
754 } else if (ui->auth_description != NULL &&
755 strncmp("ServerAuthenticate", ui->auth_description, 18) == 0)
757 if (ui->netlogon_trust_account.negotiate_flags
758 & NETLOGON_NEG_SUPPORTS_AES) {
759 password_type = "HMAC-SHA256";
760 } else if (ui->netlogon_trust_account.negotiate_flags
761 & NETLOGON_NEG_STRONG_KEYS) {
762 password_type = "HMAC-MD5";
763 } else {
764 password_type = "DES";
766 } else if (ui->password_state == AUTH_PASSWORD_RESPONSE &&
767 (ui->logon_parameters & MSV1_0_ALLOW_MSVCHAPV2) &&
768 ui->password.response.nt.length == 24) {
769 password_type = "MSCHAPv2";
770 } else if ((ui->logon_parameters & MSV1_0_CLEARTEXT_PASSWORD_SUPPLIED)
771 || (ui->password_state == AUTH_PASSWORD_PLAIN)) {
772 password_type = "Plaintext";
773 } else if (ui->password_state == AUTH_PASSWORD_HASH) {
774 password_type = "Supplied-NT-Hash";
775 } else if (ui->password_state == AUTH_PASSWORD_RESPONSE
776 && ui->password.response.nt.length > 24) {
777 password_type = "NTLMv2";
778 } else if (ui->password_state == AUTH_PASSWORD_RESPONSE
779 && ui->password.response.nt.length == 24) {
780 password_type = "NTLMv1";
781 } else if (ui->password_state == AUTH_PASSWORD_RESPONSE
782 && ui->password.response.lanman.length == 24) {
783 password_type = "LANMan";
784 } else if (ui->password_state == AUTH_PASSWORD_RESPONSE
785 && ui->password.response.nt.length == 0
786 && ui->password.response.lanman.length == 0) {
787 password_type = "No-Password";
789 return password_type;
793 * Write a human readable authentication log entry.
796 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)
804 TALLOC_CTX *frame = NULL;
806 const char *ts = NULL; /* formatted current time */
807 char *remote = NULL; /* formatted remote host */
808 char *local = NULL; /* formatted local host */
809 char *nl = NULL; /* NETLOGON details if present */
810 char *trust_computer_name = NULL;
811 char *trust_account_name = NULL;
812 char *logon_line = NULL;
813 const char *password_type = NULL;
814 const char *clientDomain = ui->orig_client.domain_name ?
815 ui->orig_client.domain_name :
816 ui->client.domain_name;
817 const char *clientAccount = ui->orig_client.account_name ?
818 ui->orig_client.account_name :
819 ui->client.account_name;
821 frame = talloc_stackframe();
823 password_type = get_password_type(ui);
824 /* Get the current time */
825 ts = audit_get_timestamp(frame);
827 /* Only log the NETLOGON details if they are present */
828 if (ui->netlogon_trust_account.computer_name ||
829 ui->netlogon_trust_account.account_name) {
830 trust_computer_name = log_escape(frame,
831 ui->netlogon_trust_account.computer_name);
832 trust_account_name = log_escape(frame,
833 ui->netlogon_trust_account.account_name);
834 nl = talloc_asprintf(frame,
835 " NETLOGON computer [%s] trust account [%s]",
836 trust_computer_name, trust_account_name);
839 remote = tsocket_address_string(ui->remote_host, frame);
840 local = tsocket_address_string(ui->local_host, frame);
842 if (NT_STATUS_IS_OK(status)) {
843 struct dom_sid_buf sid_buf;
845 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 logon_line = talloc_asprintf(
852 frame,
853 " mapped to [%s]\\[%s].",
854 log_escape(frame, ui->mapped.domain_name),
855 log_escape(frame, ui->mapped.account_name));
858 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),
869 password_type,
870 nt_errstr(status),
871 log_escape(frame, ui->workstation_name),
872 remote,
873 logon_line,
874 local,
875 nl ? nl : ""
878 talloc_free(frame);
882 * Log details of an authentication attempt.
883 * Successful and unsuccessful attempts are logged.
885 * NOTE: msg_ctx and lp_ctx is optional, but when supplied allows streaming the
886 * authentication events over the message bus.
888 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)
900 /* set the log level */
901 int debug_level = AUTH_FAILURE_LEVEL;
902 enum event_id_type event_id = EVT_ID_UNSUCCESSFUL_LOGON;
904 if (NT_STATUS_IS_OK(status)) {
905 debug_level = AUTH_SUCCESS_LEVEL;
906 event_id = EVT_ID_SUCCESSFUL_LOGON;
907 if (dom_sid_equal(sid, &global_sid_Anonymous)) {
908 debug_level = AUTH_ANONYMOUS_LEVEL;
912 if (CHECK_DEBUGLVLC(DBGC_AUTH_AUDIT, debug_level)) {
913 log_authentication_event_human_readable(ui,
914 status,
915 domain_name,
916 account_name,
917 sid,
918 debug_level);
920 if (CHECK_DEBUGLVLC(DBGC_AUTH_AUDIT_JSON, debug_level) ||
921 (msg_ctx && lp_ctx && lpcfg_auth_event_notification(lp_ctx))) {
922 log_authentication_event_json(msg_ctx,
923 lp_ctx,
924 start_time,
926 status,
927 domain_name,
928 account_name,
929 sid,
930 client_audit_info,
931 server_audit_info,
932 event_id,
933 debug_level);
940 * Log details of a successful authorization to a service,
941 * in a human readable format.
944 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)
952 TALLOC_CTX *frame = NULL;
954 const char *ts = NULL; /* formatted current time */
955 char *remote_str = NULL; /* formatted remote host */
956 char *local_str = NULL; /* formatted local host */
957 struct dom_sid_buf sid_buf;
959 frame = talloc_stackframe();
961 /* Get the current time */
962 ts = audit_get_timestamp(frame);
964 remote_str = tsocket_address_string(remote, frame);
965 local_str = tsocket_address_string(local, frame);
967 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),
979 remote_str,
980 local_str));
982 talloc_free(frame);
986 * Log details of a successful authorization to a service.
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
992 * The service may later refuse authorization due to an ACL.
994 * NOTE: msg_ctx and lp_ctx is optional, but when supplied allows streaming the
995 * authentication events over the message bus.
997 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)
1009 int debug_level = AUTHZ_SUCCESS_LEVEL;
1011 /* set the log level */
1012 if (security_token_is_anonymous(session_info->security_token)) {
1013 debug_level = AUTH_ANONYMOUS_LEVEL;
1016 if (CHECK_DEBUGLVLC(DBGC_AUTH_AUDIT, debug_level)) {
1017 log_successful_authz_event_human_readable(remote,
1018 local,
1019 service_description,
1020 auth_type,
1021 session_info,
1022 debug_level);
1024 if (CHECK_DEBUGLVLC(DBGC_AUTH_AUDIT_JSON, debug_level) ||
1025 (msg_ctx && lp_ctx && lpcfg_auth_event_notification(lp_ctx))) {
1026 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);
1040 * Log details of an authorization to a service.
1042 * NOTE: msg_ctx and lp_ctx are optional, but when supplied, allow streaming the
1043 * authorization events over the message bus.
1045 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)
1060 /* set the log level */
1061 int debug_level = KDC_AUTHZ_FAILURE_LEVEL;
1063 if (NT_STATUS_IS_OK(status)) {
1064 debug_level = KDC_AUTHZ_SUCCESS_LEVEL;
1067 if (CHECK_DEBUGLVLC(DBGC_AUTH_AUDIT_JSON, debug_level) ||
1068 (msg_ctx && lp_ctx && lpcfg_auth_event_notification(lp_ctx))) {
1069 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);