VERSION: Bump version up to Samba 4.18.12...
[samba.git] / auth / auth_log.c
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
29 /* 5 is used for both authentication and authorization */
30 #define AUTH_ANONYMOUS_LEVEL 5
31 #define AUTHZ_ANONYMOUS_LEVEL 5
32
33 #define AUTHZ_JSON_TYPE "Authorization"
34 #define AUTH_JSON_TYPE  "Authentication"
35
36 /*
37  * JSON message version numbers
38  *
39  * If adding a field increment the minor version
40  * If removing or changing the format/meaning of a field
41  * increment the major version.
42  */
43 #define AUTH_MAJOR 1
44 #define AUTH_MINOR 2
45 #define AUTHZ_MAJOR 1
46 #define AUTHZ_MINOR 1
47
48 #include "includes.h"
49 #include "../lib/tsocket/tsocket.h"
50 #include "common_auth.h"
51 #include "lib/util/util_str_escape.h"
52 #include "libcli/security/dom_sid.h"
53 #include "libcli/security/security_token.h"
54 #include "librpc/gen_ndr/server_id.h"
55 #include "source4/lib/messaging/messaging.h"
56 #include "source4/lib/messaging/irpc.h"
57 #include "lib/util/server_id_db.h"
58 #include "lib/param/param.h"
59 #include "librpc/ndr/libndr.h"
60 #include "librpc/gen_ndr/windows_event_ids.h"
61 #include "lib/audit_logging/audit_logging.h"
62
63 /*
64  * Determine the type of the password supplied for the
65  * authorisation attempt.
66  *
67  */
68 static const char* get_password_type(const struct auth_usersupplied_info *ui);
69
70 #ifdef HAVE_JANSSON
71
72 #include <jansson.h>
73 #include "system/time.h"
74
75 /*
76  * Write the json object to the debug logs.
77  *
78  */
79 static void log_json(struct imessaging_context *msg_ctx,
80                      struct loadparm_context *lp_ctx,
81                      struct json_object *object,
82                      int debug_class,
83                      int debug_level)
84 {
85         audit_log_json(object, debug_class, debug_level);
86         if (msg_ctx && lp_ctx && lpcfg_auth_event_notification(lp_ctx)) {
87                 audit_message_send(msg_ctx,
88                                    AUTH_EVENT_NAME,
89                                    MSG_AUTH_LOG,
90                                    object);
91         }
92 }
93
94 /*
95  * Determine the Windows logon type for the current authorisation attempt.
96  *
97  * Currently Samba only supports
98  *
99  * 2 Interactive      A user logged on to this computer.
100  * 3 Network          A user or computer logged on to this computer from
101  *                    the network.
102  * 8 NetworkCleartext A user logged on to this computer from the network.
103  *                    The user's password was passed to the authentication
104  *                    package in its unhashed form.
105  *
106  */
107 static enum event_logon_type get_logon_type(
108         const struct auth_usersupplied_info *ui)
109 {
110         if ((ui->logon_parameters & MSV1_0_CLEARTEXT_PASSWORD_SUPPLIED)
111            || (ui->password_state == AUTH_PASSWORD_PLAIN)) {
112                 return EVT_LOGON_NETWORK_CLEAR_TEXT;
113         } else if (ui->flags & USER_INFO_INTERACTIVE_LOGON) {
114                 return EVT_LOGON_INTERACTIVE;
115         }
116         return EVT_LOGON_NETWORK;
117 }
118
119 /*
120  * Write a machine parsable json formatted authentication log entry.
121  *
122  * IF removing or changing the format/meaning of a field please update the
123  *    major version number AUTH_MAJOR
124  *
125  * IF adding a new field please update the minor version number AUTH_MINOR
126  *
127  *  To process the resulting log lines from the commend line use jq to
128  *  parse the json.
129  *
130  *  grep "^  {" log file |
131  *  jq -rc '"\(.timestamp)\t\(.Authentication.status)\t
132  *           \(.Authentication.clientDomain)\t
133  *           \(.Authentication.clientAccount)
134  *           \t\(.Authentication.workstation)
135  *           \t\(.Authentication.remoteAddress)
136  *           \t\(.Authentication.localAddress)"'
137  */
138 static void log_authentication_event_json(
139         struct imessaging_context *msg_ctx,
140         struct loadparm_context *lp_ctx,
141         const struct timeval *start_time,
142         const struct auth_usersupplied_info *ui,
143         NTSTATUS status,
144         const char *domain_name,
145         const char *account_name,
146         struct dom_sid *sid,
147         enum event_id_type event_id,
148         int debug_level)
149 {
150         struct json_object wrapper = json_empty_object;
151         struct json_object authentication = json_empty_object;
152         char negotiate_flags[11];
153         char logon_id[19];
154         int rc = 0;
155         const char *clientDomain = ui->orig_client.domain_name ?
156                                    ui->orig_client.domain_name :
157                                    ui->client.domain_name;
158         const char *clientAccount = ui->orig_client.account_name ?
159                                     ui->orig_client.account_name :
160                                     ui->client.account_name;
161
162         authentication = json_new_object();
163         if (json_is_invalid(&authentication)) {
164                 goto failure;
165         }
166         rc = json_add_version(&authentication, AUTH_MAJOR, AUTH_MINOR);
167         if (rc != 0) {
168                 goto failure;
169         }
170         rc = json_add_int(&authentication,
171                           "eventId",
172                           event_id);
173         if (rc != 0) {
174                 goto failure;
175         }
176         snprintf(logon_id,
177                  sizeof( logon_id),
178                  "%"PRIx64"",
179                  ui->logon_id);
180         rc = json_add_string(&authentication, "logonId", logon_id);
181         if (rc != 0) {
182                 goto failure;
183         }
184         rc = json_add_int(&authentication, "logonType", get_logon_type(ui));
185         if (rc != 0) {
186                 goto failure;
187         }
188         rc = json_add_string(&authentication, "status", nt_errstr(status));
189         if (rc != 0) {
190                 goto failure;
191         }
192         rc = json_add_address(&authentication, "localAddress", ui->local_host);
193         if (rc != 0) {
194                 goto failure;
195         }
196         rc =
197             json_add_address(&authentication, "remoteAddress", ui->remote_host);
198         if (rc != 0) {
199                 goto failure;
200         }
201         rc = json_add_string(
202             &authentication, "serviceDescription", ui->service_description);
203         if (rc != 0) {
204                 goto failure;
205         }
206         rc = json_add_string(
207             &authentication, "authDescription", ui->auth_description);
208         if (rc != 0) {
209                 goto failure;
210         }
211         rc = json_add_string(
212             &authentication, "clientDomain", clientDomain);
213         if (rc != 0) {
214                 goto failure;
215         }
216         rc = json_add_string(
217             &authentication, "clientAccount", clientAccount);
218         if (rc != 0) {
219                 goto failure;
220         }
221         rc = json_add_string(
222             &authentication, "workstation", ui->workstation_name);
223         if (rc != 0) {
224                 goto failure;
225         }
226         rc = json_add_string(&authentication, "becameAccount", account_name);
227         if (rc != 0) {
228                 goto failure;
229         }
230         rc = json_add_string(&authentication, "becameDomain", domain_name);
231         if (rc != 0) {
232                 goto failure;
233         }
234         rc = json_add_sid(&authentication, "becameSid", sid);
235         if (rc != 0) {
236                 goto failure;
237         }
238         rc = json_add_string(
239             &authentication, "mappedAccount", ui->mapped.account_name);
240         if (rc != 0) {
241                 goto failure;
242         }
243         rc = json_add_string(
244             &authentication, "mappedDomain", ui->mapped.domain_name);
245         if (rc != 0) {
246                 goto failure;
247         }
248         rc = json_add_string(&authentication,
249                              "netlogonComputer",
250                              ui->netlogon_trust_account.computer_name);
251         if (rc != 0) {
252                 goto failure;
253         }
254         rc = json_add_string(&authentication,
255                              "netlogonTrustAccount",
256                              ui->netlogon_trust_account.account_name);
257         if (rc != 0) {
258                 goto failure;
259         }
260         snprintf(negotiate_flags,
261                  sizeof( negotiate_flags),
262                  "0x%08X",
263                  ui->netlogon_trust_account.negotiate_flags);
264         rc = json_add_string(
265             &authentication, "netlogonNegotiateFlags", negotiate_flags);
266         if (rc != 0) {
267                 goto failure;
268         }
269         rc = json_add_int(&authentication,
270                           "netlogonSecureChannelType",
271                           ui->netlogon_trust_account.secure_channel_type);
272         if (rc != 0) {
273                 goto failure;
274         }
275         rc = json_add_sid(&authentication,
276                           "netlogonTrustAccountSid",
277                           ui->netlogon_trust_account.sid);
278         if (rc != 0) {
279                 goto failure;
280         }
281         rc = json_add_string(
282             &authentication, "passwordType", get_password_type(ui));
283         if (rc != 0) {
284                 goto failure;
285         }
286
287         wrapper = json_new_object();
288         if (json_is_invalid(&wrapper)) {
289                 goto failure;
290         }
291         rc = json_add_timestamp(&wrapper);
292         if (rc != 0) {
293                 goto failure;
294         }
295         rc = json_add_string(&wrapper, "type", AUTH_JSON_TYPE);
296         if (rc != 0) {
297                 goto failure;
298         }
299         rc = json_add_object(&wrapper, AUTH_JSON_TYPE, &authentication);
300         if (rc != 0) {
301                 goto failure;
302         }
303
304         /*
305          * While not a general-purpose profiling solution this will
306          * assist some to determine how long NTLM and KDC
307          * authentication takes once this process can handle it.  This
308          * covers transactions elsewhere but not (eg) the delay while
309          * this is waiting unread on the input socket.
310          */
311         if (start_time != NULL) {
312                 struct timeval current_time = timeval_current();
313                 uint64_t duration =  usec_time_diff(&current_time,
314                                                     start_time);
315                 rc = json_add_int(&authentication, "duration", duration);
316                 if (rc != 0) {
317                         goto failure;
318                 }
319         }
320
321         log_json(msg_ctx,
322                  lp_ctx,
323                  &wrapper,
324                  DBGC_AUTH_AUDIT_JSON,
325                  debug_level);
326         json_free(&wrapper);
327         return;
328 failure:
329         /*
330          * On a failure authentication will not have been added to wrapper so it
331          * needs to be freed to avoid a leak.
332          *
333          */
334         json_free(&authentication);
335         json_free(&wrapper);
336         DBG_ERR("Failed to write authentication event JSON log message\n");
337 }
338
339 /*
340  * Log details of a successful authorization to a service,
341  * in a machine parsable json format
342  *
343  * IF removing or changing the format/meaning of a field please update the
344  *    major version number AUTHZ_MAJOR
345  *
346  * IF adding a new field please update the minor version number AUTHZ_MINOR
347  *
348  *  To process the resulting log lines from the commend line use jq to
349  *  parse the json.
350  *
351  *  grep "^  {" log_file |\
352  *  jq -rc '"\(.timestamp)\t
353  *           \(.Authorization.domain)\t
354  *           \(.Authorization.account)\t
355  *           \(.Authorization.remoteAddress)"'
356  *
357  */
358 static void log_successful_authz_event_json(
359         struct imessaging_context *msg_ctx,
360         struct loadparm_context *lp_ctx,
361         const struct tsocket_address *remote,
362         const struct tsocket_address *local,
363         const char *service_description,
364         const char *auth_type,
365         const char *transport_protection,
366         struct auth_session_info *session_info,
367         int debug_level)
368 {
369         struct json_object wrapper = json_empty_object;
370         struct json_object authorization = json_empty_object;
371         char account_flags[11];
372         int rc = 0;
373
374         authorization = json_new_object();
375         if (json_is_invalid(&authorization)) {
376                 goto failure;
377         }
378         rc = json_add_version(&authorization, AUTHZ_MAJOR, AUTHZ_MINOR);
379         if (rc != 0) {
380                 goto failure;
381         }
382         rc = json_add_address(&authorization, "localAddress", local);
383         if (rc != 0) {
384                 goto failure;
385         }
386         rc = json_add_address(&authorization, "remoteAddress", remote);
387         if (rc != 0) {
388                 goto failure;
389         }
390         rc = json_add_string(
391             &authorization, "serviceDescription", service_description);
392         if (rc != 0) {
393                 goto failure;
394         }
395         rc = json_add_string(&authorization, "authType", auth_type);
396         if (rc != 0) {
397                 goto failure;
398         }
399         rc = json_add_string(
400             &authorization, "domain", session_info->info->domain_name);
401         if (rc != 0) {
402                 goto failure;
403         }
404         rc = json_add_string(
405             &authorization, "account", session_info->info->account_name);
406         if (rc != 0) {
407                 goto failure;
408         }
409         rc = json_add_sid(
410             &authorization, "sid", &session_info->security_token->sids[0]);
411         if (rc != 0) {
412                 goto failure;
413         }
414         rc = json_add_guid(
415             &authorization, "sessionId", &session_info->unique_session_token);
416         if (rc != 0) {
417                 goto failure;
418         }
419         rc = json_add_string(
420             &authorization, "logonServer", session_info->info->logon_server);
421         if (rc != 0) {
422                 goto failure;
423         }
424         rc = json_add_string(
425             &authorization, "transportProtection", transport_protection);
426         if (rc != 0) {
427                 goto failure;
428         }
429
430         snprintf(account_flags,
431                  sizeof(account_flags),
432                  "0x%08X",
433                  session_info->info->acct_flags);
434         rc = json_add_string(&authorization, "accountFlags", account_flags);
435         if (rc != 0) {
436                 goto failure;
437         }
438
439         wrapper = json_new_object();
440         if (json_is_invalid(&wrapper)) {
441                 goto failure;
442         }
443         rc = json_add_timestamp(&wrapper);
444         if (rc != 0) {
445                 goto failure;
446         }
447         rc = json_add_string(&wrapper, "type", AUTHZ_JSON_TYPE);
448         if (rc != 0) {
449                 goto failure;
450         }
451         rc = json_add_object(&wrapper, AUTHZ_JSON_TYPE, &authorization);
452         if (rc != 0) {
453                 goto failure;
454         }
455
456         log_json(msg_ctx,
457                  lp_ctx,
458                  &wrapper,
459                  DBGC_AUTH_AUDIT_JSON,
460                  debug_level);
461         json_free(&wrapper);
462         return;
463 failure:
464         /*
465          * On a failure authorization will not have been added to wrapper so it
466          * needs to be freed to avoid a leak.
467          *
468          */
469         json_free(&authorization);
470         json_free(&wrapper);
471         DBG_ERR("Unable to log Authentication event JSON audit message\n");
472 }
473
474 #else
475
476 static void log_no_json(struct imessaging_context *msg_ctx,
477                         struct loadparm_context *lp_ctx)
478 {
479         if (msg_ctx && lp_ctx && lpcfg_auth_event_notification(lp_ctx)) {
480                 static bool auth_event_logged = false;
481                 if (auth_event_logged == false) {
482                         auth_event_logged = true;
483                         DBG_ERR("auth event notification = true but Samba was "
484                                 "not compiled with jansson\n");
485                 }
486         } else {
487                 static bool json_logged = false;
488                 if (json_logged == false) {
489                         json_logged = true;
490                         DBG_NOTICE("JSON auth logs not available unless "
491                                    "compiled with jansson\n");
492                 }
493         }
494
495         return;
496 }
497
498 static void log_authentication_event_json(
499         struct imessaging_context *msg_ctx,
500         struct loadparm_context *lp_ctx,
501         const struct timeval *start_time,
502         const struct auth_usersupplied_info *ui,
503         NTSTATUS status,
504         const char *domain_name,
505         const char *account_name,
506         struct dom_sid *sid,
507         enum event_id_type event_id,
508         int debug_level)
509 {
510         log_no_json(msg_ctx, lp_ctx);
511         return;
512 }
513
514 static void log_successful_authz_event_json(
515         struct imessaging_context *msg_ctx,
516         struct loadparm_context *lp_ctx,
517         const struct tsocket_address *remote,
518         const struct tsocket_address *local,
519         const char *service_description,
520         const char *auth_type,
521         const char *transport_protection,
522         struct auth_session_info *session_info,
523         int debug_level)
524 {
525         log_no_json(msg_ctx, lp_ctx);
526         return;
527 }
528
529 #endif
530
531 /*
532  * Determine the type of the password supplied for the
533  * authorisation attempt.
534  *
535  */
536 static const char* get_password_type(const struct auth_usersupplied_info *ui)
537 {
538
539         const char *password_type = NULL;
540
541         if (ui->password_type != NULL) {
542                 password_type = ui->password_type;
543         } else if (ui->auth_description != NULL &&
544                    strncmp("ServerAuthenticate", ui->auth_description, 18) == 0)
545         {
546                 if (ui->netlogon_trust_account.negotiate_flags
547                     & NETLOGON_NEG_SUPPORTS_AES) {
548                         password_type = "HMAC-SHA256";
549                 } else if (ui->netlogon_trust_account.negotiate_flags
550                            & NETLOGON_NEG_STRONG_KEYS) {
551                         password_type = "HMAC-MD5";
552                 } else {
553                         password_type = "DES";
554                 }
555         } else if (ui->password_state == AUTH_PASSWORD_RESPONSE &&
556                    (ui->logon_parameters & MSV1_0_ALLOW_MSVCHAPV2) &&
557                    ui->password.response.nt.length == 24) {
558                 password_type = "MSCHAPv2";
559         } else if ((ui->logon_parameters & MSV1_0_CLEARTEXT_PASSWORD_SUPPLIED)
560                    || (ui->password_state == AUTH_PASSWORD_PLAIN)) {
561                 password_type = "Plaintext";
562         } else if (ui->password_state == AUTH_PASSWORD_HASH) {
563                 password_type = "Supplied-NT-Hash";
564         } else if (ui->password_state == AUTH_PASSWORD_RESPONSE
565                    && ui->password.response.nt.length > 24) {
566                 password_type = "NTLMv2";
567         } else if (ui->password_state == AUTH_PASSWORD_RESPONSE
568                    && ui->password.response.nt.length == 24) {
569                 password_type = "NTLMv1";
570         } else if (ui->password_state == AUTH_PASSWORD_RESPONSE
571                    && ui->password.response.lanman.length == 24) {
572                 password_type = "LANMan";
573         } else if (ui->password_state == AUTH_PASSWORD_RESPONSE
574                    && ui->password.response.nt.length == 0
575                    && ui->password.response.lanman.length == 0) {
576                 password_type = "No-Password";
577         }
578         return password_type;
579 }
580
581 /*
582  * Write a human readable authentication log entry.
583  *
584  */
585 static void log_authentication_event_human_readable(
586         const struct auth_usersupplied_info *ui,
587         NTSTATUS status,
588         const char *domain_name,
589         const char *account_name,
590         struct dom_sid *sid,
591         int debug_level)
592 {
593         TALLOC_CTX *frame = NULL;
594
595         const char *ts = NULL;             /* formatted current time      */
596         char *remote = NULL;               /* formatted remote host       */
597         char *local = NULL;                /* formatted local host        */
598         char *nl = NULL;                   /* NETLOGON details if present */
599         char *trust_computer_name = NULL;
600         char *trust_account_name = NULL;
601         char *logon_line = NULL;
602         const char *password_type = NULL;
603         const char *clientDomain = ui->orig_client.domain_name ?
604                                    ui->orig_client.domain_name :
605                                    ui->client.domain_name;
606         const char *clientAccount = ui->orig_client.account_name ?
607                                     ui->orig_client.account_name :
608                                     ui->client.account_name;
609
610         frame = talloc_stackframe();
611
612         password_type = get_password_type(ui);
613         /* Get the current time */
614         ts = audit_get_timestamp(frame);
615
616         /* Only log the NETLOGON details if they are present */
617         if (ui->netlogon_trust_account.computer_name ||
618             ui->netlogon_trust_account.account_name) {
619                 trust_computer_name = log_escape(frame,
620                         ui->netlogon_trust_account.computer_name);
621                 trust_account_name  = log_escape(frame,
622                         ui->netlogon_trust_account.account_name);
623                 nl = talloc_asprintf(frame,
624                         " NETLOGON computer [%s] trust account [%s]",
625                         trust_computer_name, trust_account_name);
626         }
627
628         remote = tsocket_address_string(ui->remote_host, frame);
629         local = tsocket_address_string(ui->local_host, frame);
630
631         if (NT_STATUS_IS_OK(status)) {
632                 struct dom_sid_buf sid_buf;
633
634                 logon_line = talloc_asprintf(frame,
635                                              " became [%s]\\[%s] [%s].",
636                                              log_escape(frame, domain_name),
637                                              log_escape(frame, account_name),
638                                              dom_sid_str_buf(sid, &sid_buf));
639         } else {
640                 logon_line = talloc_asprintf(
641                                 frame,
642                                 " mapped to [%s]\\[%s].",
643                                 log_escape(frame, ui->mapped.domain_name),
644                                 log_escape(frame, ui->mapped.account_name));
645         }
646
647         DEBUGC(DBGC_AUTH_AUDIT, debug_level,
648                ("Auth: [%s,%s] user [%s]\\[%s]"
649                 " at [%s] with [%s] status [%s]"
650                 " workstation [%s] remote host [%s]"
651                 "%s local host [%s]"
652                 " %s\n",
653                 ui->service_description,
654                 ui->auth_description,
655                 log_escape(frame, clientDomain),
656                 log_escape(frame, clientAccount),
657                 ts,
658                 password_type,
659                 nt_errstr(status),
660                 log_escape(frame, ui->workstation_name),
661                 remote,
662                 logon_line,
663                 local,
664                 nl ? nl : ""
665         ));
666
667         talloc_free(frame);
668 }
669
670 /*
671  * Log details of an authentication attempt.
672  * Successful and unsuccessful attempts are logged.
673  *
674  * NOTE: msg_ctx and lp_ctx is optional, but when supplied allows streaming the
675  * authentication events over the message bus.
676  */
677 void log_authentication_event(
678         struct imessaging_context *msg_ctx,
679         struct loadparm_context *lp_ctx,
680         const struct timeval *start_time,
681         const struct auth_usersupplied_info *ui,
682         NTSTATUS status,
683         const char *domain_name,
684         const char *account_name,
685         struct dom_sid *sid)
686 {
687         /* set the log level */
688         int debug_level = AUTH_FAILURE_LEVEL;
689         enum event_id_type event_id = EVT_ID_UNSUCCESSFUL_LOGON;
690
691         if (NT_STATUS_IS_OK(status)) {
692                 debug_level = AUTH_SUCCESS_LEVEL;
693                 event_id = EVT_ID_SUCCESSFUL_LOGON;
694                 if (dom_sid_equal(sid, &global_sid_Anonymous)) {
695                         debug_level = AUTH_ANONYMOUS_LEVEL;
696                 }
697         }
698
699         if (CHECK_DEBUGLVLC(DBGC_AUTH_AUDIT, debug_level)) {
700                 log_authentication_event_human_readable(ui,
701                                                         status,
702                                                         domain_name,
703                                                         account_name,
704                                                         sid,
705                                                         debug_level);
706         }
707         if (CHECK_DEBUGLVLC(DBGC_AUTH_AUDIT_JSON, debug_level) ||
708             (msg_ctx && lp_ctx && lpcfg_auth_event_notification(lp_ctx))) {
709                 log_authentication_event_json(msg_ctx,
710                                               lp_ctx,
711                                               start_time,
712                                               ui,
713                                               status,
714                                               domain_name,
715                                               account_name,
716                                               sid,
717                                               event_id,
718                                               debug_level);
719         }
720 }
721
722
723
724 /*
725  * Log details of a successful authorization to a service,
726  * in a human readable format.
727  *
728  */
729 static void log_successful_authz_event_human_readable(
730         const struct tsocket_address *remote,
731         const struct tsocket_address *local,
732         const char *service_description,
733         const char *auth_type,
734         struct auth_session_info *session_info,
735         int debug_level)
736 {
737         TALLOC_CTX *frame = NULL;
738
739         const char *ts = NULL;       /* formatted current time      */
740         char *remote_str = NULL;     /* formatted remote host       */
741         char *local_str = NULL;      /* formatted local host        */
742         struct dom_sid_buf sid_buf;
743
744         frame = talloc_stackframe();
745
746         /* Get the current time */
747         ts = audit_get_timestamp(frame);
748
749         remote_str = tsocket_address_string(remote, frame);
750         local_str = tsocket_address_string(local, frame);
751
752         DEBUGC(DBGC_AUTH_AUDIT, debug_level,
753                ("Successful AuthZ: [%s,%s] user [%s]\\[%s] [%s]"
754                 " at [%s]"
755                 " Remote host [%s]"
756                 " local host [%s]\n",
757                 service_description,
758                 auth_type,
759                 log_escape(frame, session_info->info->domain_name),
760                 log_escape(frame, session_info->info->account_name),
761                 dom_sid_str_buf(&session_info->security_token->sids[0],
762                                 &sid_buf),
763                 ts,
764                 remote_str,
765                 local_str));
766
767         talloc_free(frame);
768 }
769
770 /*
771  * Log details of a successful authorization to a service.
772  *
773  * Only successful authorizations are logged.  For clarity:
774  * - NTLM bad passwords will be recorded by log_authentication_event
775  * - Kerberos decrypt failures need to be logged in gensec_gssapi et al
776  *
777  * The service may later refuse authorization due to an ACL.
778  *
779  * NOTE: msg_ctx and lp_ctx is optional, but when supplied allows streaming the
780  * authentication events over the message bus.
781  */
782 void log_successful_authz_event(
783         struct imessaging_context *msg_ctx,
784         struct loadparm_context *lp_ctx,
785         const struct tsocket_address *remote,
786         const struct tsocket_address *local,
787         const char *service_description,
788         const char *auth_type,
789         const char *transport_protection,
790         struct auth_session_info *session_info)
791 {
792         int debug_level = AUTHZ_SUCCESS_LEVEL;
793
794         /* set the log level */
795         if (security_token_is_anonymous(session_info->security_token)) {
796                 debug_level = AUTH_ANONYMOUS_LEVEL;
797         }
798
799         if (CHECK_DEBUGLVLC(DBGC_AUTH_AUDIT, debug_level)) {
800                 log_successful_authz_event_human_readable(remote,
801                                                           local,
802                                                           service_description,
803                                                           auth_type,
804                                                           session_info,
805                                                           debug_level);
806         }
807         if (CHECK_DEBUGLVLC(DBGC_AUTH_AUDIT_JSON, debug_level) ||
808             (msg_ctx && lp_ctx && lpcfg_auth_event_notification(lp_ctx))) {
809                 log_successful_authz_event_json(msg_ctx, lp_ctx,
810                                                 remote,
811                                                 local,
812                                                 service_description,
813                                                 auth_type,
814                                                 transport_protection,
815                                                 session_info,
816                                                 debug_level);
817         }
818 }