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