auth_log: Add JSON logging of Authorisation and Authentications
[metze/samba/wip.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 0
45 #define AUTHZ_MAJOR 1
46 #define AUTHZ_MINOR 0
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
55 /*
56  * Get a human readable timestamp.
57  *
58  * Returns the current time formatted as
59  *  "Tue, 14 Mar 2017 08:38:42.209028 NZDT"
60  *
61  * The returned string is allocated by talloc in the supplied context.
62  * It is the callers responsibility to free it.
63  *
64  */
65 static const char* get_timestamp( TALLOC_CTX *frame )
66 {
67         char buffer[40];        /* formatted time less usec and timezone */
68         char tz[10];            /* formatted time zone                   */
69         struct tm* tm_info;     /* current local time                    */
70         struct timeval tv;      /* current system time                   */
71         int r;                  /* response code from gettimeofday       */
72         const char * ts;        /* formatted time stamp                  */
73
74         r = gettimeofday(&tv, NULL);
75         if (r) {
76                 DBG_ERR("Unable to get time of day: (%d) %s\n",
77                         errno,
78                         strerror( errno));
79                 return NULL;
80         }
81
82         tm_info = localtime(&tv.tv_sec);
83         if (tm_info == NULL) {
84                 DBG_ERR("Unable to determine local time\n");
85                 return NULL;
86         }
87
88         strftime(buffer, sizeof(buffer)-1, "%a, %d %b %Y %H:%M:%S", tm_info);
89         strftime(tz, sizeof(tz)-1, "%Z", tm_info);
90         ts = talloc_asprintf(frame, "%s.%06ld %s", buffer, tv.tv_usec, tz);
91         if (ts == NULL) {
92                 DBG_ERR("Out of memory formatting time stamp\n");
93         }
94         return ts;
95 }
96
97 /*
98  * Determine the type of the password supplied for the
99  * authorisation attempt.
100  *
101  */
102 static const char* get_password_type(const struct auth_usersupplied_info *ui);
103
104 #ifdef HAVE_JANSSON
105
106 #include <jansson.h>
107 #include "system/time.h"
108
109 /*
110  * Context required by the JSON generation
111  *  routines
112  *
113  */
114 struct json_context {
115         json_t *root;
116         bool error;
117 };
118
119 /*
120  * Write the json object to the debug lines.
121  *
122  */
123 static void log_json( struct json_context *context,
124                      const char *type, int debug_class, int debug_level)
125 {
126         char* json = NULL;
127
128         if( context->error) {
129                 return;
130         }
131
132         json = json_dumps( context->root, 0);
133         if (json == NULL) {
134                 DBG_ERR( "Unable to convert JSON object to string\n");
135                 context->error = true;
136                 return;
137         }
138
139         DEBUGC( debug_class, debug_level, ( "JSON %s: %s\n", type, json));
140
141         if (json) {
142                 free(json);
143         }
144
145 }
146
147 /*
148  * Create a new json logging context.
149  *
150  * Free with a call to free_json_context
151  *
152  */
153 static struct json_context get_json_context( void) {
154
155         struct json_context context;
156         context.error = false;
157
158         context.root = json_object();
159         if (context.root == NULL) {
160                 context.error = true;
161                 DBG_ERR("Unable to create json_object\n");
162         }
163         return context;
164 }
165
166 /*
167  * free a previously created json_context
168  *
169  */
170 static void free_json_context(struct json_context *context)
171 {
172         if (context->root) {
173                 json_decref( context->root);
174         }
175 }
176
177 /*
178  * Output a JSON pair with name name and integer value value
179  *
180  */
181 static void add_int(struct json_context *context,
182                     const char* name,
183                     const int value)
184 {
185         int rc = 0;
186
187         if (context->error) {
188                 return;
189         }
190
191         rc = json_object_set_new( context->root, name, json_integer( value));
192         if (rc) {
193                 DBG_ERR("Unable to set name [%s] value [%d]\n", name, value);
194                 context->error = true;
195         }
196
197 }
198
199 /*
200  * Output a JSON pair with name name and string value value
201  *
202  */
203 static void add_string(struct json_context *context,
204                        const char* name,
205                        const char* value)
206 {
207         int rc = 0;
208
209         if (context->error) {
210                 return;
211         }
212
213         if (value) {
214                 rc = json_object_set_new(context->root, name, json_string(value));
215         } else {
216                 rc = json_object_set_new(context->root, name, json_null());
217         }
218         if (rc) {
219                 DBG_ERR("Unable to set name [%s] value [%s]\n", name, value);
220                 context->error = true;
221         }
222 }
223
224
225 /*
226  * Output a JSON pair with name name and object value
227  *
228  */
229 static void add_object(struct json_context *context,
230                        const char* name,
231                        struct json_context *value)
232 {
233         int rc = 0;
234
235         if (value->error) {
236                 context->error = true;
237         }
238         if (context->error) {
239                 return;
240         }
241         rc = json_object_set_new(context->root, name, value->root);
242         if (rc) {
243                 DBG_ERR("Unable to add object [%s]\n", name);
244                 context->error = true;
245         }
246 }
247
248 /*
249  * Output a version object
250  *
251  * "version":{"major":1,"minor":0}
252  *
253  */
254 static void add_version( struct json_context *context, int major, int minor)
255 {
256         struct json_context version = get_json_context();
257         add_int(&version, "major", major);
258         add_int(&version, "minor", minor);
259         add_object(context, "version", &version);
260 }
261
262 /*
263  * Output the current date and time as a timestamp in ISO 8601 format
264  *
265  * "timestamp":"2017-03-06T17:18:04.455081+1300"
266  *
267  */
268 static void add_timestamp( struct json_context *context)
269 {
270         char buffer[40];        /* formatted time less usec and timezone */
271         char timestamp[50];     /* the formatted ISO 8601 time stamp     */
272         char tz[10];            /* formatted time zone                   */
273         struct tm* tm_info;     /* current local time                    */
274         struct timeval tv;      /* current system time                   */
275         int r;                  /* response code from gettimeofday       */
276
277         if (context->error) {
278                 return;
279         }
280
281         r = gettimeofday(&tv, NULL);
282         if (r) {
283                 DBG_ERR("Unable to get time of day: (%d) %s\n",
284                         errno,
285                         strerror( errno));
286                 context->error = true;
287                 return;
288         }
289
290         tm_info = localtime(&tv.tv_sec);
291         if (tm_info == NULL) {
292                 DBG_ERR("Unable to determine local time\n");
293                 context->error = true;
294                 return;
295         }
296
297         strftime(buffer, sizeof(buffer)-1, "%Y-%m-%dT%T", tm_info);
298         strftime(tz, sizeof(tz)-1, "%z", tm_info);
299         snprintf(timestamp, sizeof(timestamp),"%s.%06ld%s",
300                  buffer, tv.tv_usec, tz);
301         add_string(context,"timestamp", timestamp);
302 }
303
304
305 /*
306  * Output an address pair, with name name.
307  *
308  * "localAddress":"ipv6::::0"
309  *
310  */
311 static void add_address(struct json_context *context,
312                         const char *name,
313                         const struct tsocket_address *address)
314 {
315         char *s = NULL;
316         TALLOC_CTX *frame = talloc_stackframe();
317
318         if (context->error) {
319                 return;
320         }
321
322         s = tsocket_address_string(address, frame);
323         add_string(context, name, s);
324         talloc_free(frame);
325
326 }
327
328 /*
329  * Output a SID with name name
330  *
331  * "sid":"S-1-5-18"
332  *
333  */
334 static void add_sid(struct json_context *context,
335                     const char *name,
336                     const struct dom_sid *sid)
337 {
338         char sid_buf[DOM_SID_STR_BUFLEN];
339
340         if (context->error) {
341                 return;
342         }
343
344         dom_sid_string_buf(sid, sid_buf, sizeof(sid_buf));
345         add_string(context, name, sid_buf);
346 }
347
348 /*
349  * Write a machine parsable json formatted authentication log entry.
350  *
351  * IF removing or changing the format/meaning of a field please update the
352  *    major version number AUTH_MAJOR
353  *
354  * IF adding a new field please update the minor version number AUTH_MINOR
355  *
356  *  To process the resulting log lines from the commend line use jq to
357  *  parse the json.
358  *
359  *  grep "JSON Authentication" log file |
360  *  sed 's;^[^{]*;;' |
361  * jq -rc  '"\(.timestamp)\t\(.Authentication.status)\t
362  *           \(.Authentication.clientDomain)\t
363  *           \(.Authentication.clientAccount)
364  *           \t\(.Authentication.workstation)
365  *           \t\(.Authentication.remoteAddress)
366  *           \t\(.Authentication.localAddress)"'
367  */
368 static void log_authentication_event_json(
369                         const struct auth_usersupplied_info *ui,
370                         NTSTATUS status,
371                         const char *domain_name,
372                         const char *account_name,
373                         const char *unix_username,
374                         struct dom_sid *sid,
375                         int debug_level)
376 {
377         struct json_context context = get_json_context();
378         struct json_context authentication;
379         char negotiate_flags[11];
380
381         add_timestamp(&context);
382         add_string(&context, "type", AUTH_JSON_TYPE);
383
384         authentication = get_json_context();
385         add_version(&authentication, AUTH_MAJOR, AUTH_MINOR);
386         add_string(&authentication, "status", nt_errstr( status));
387         add_address(&authentication, "localAddress", ui->local_host);
388         add_address(&authentication, "remoteAddress", ui->remote_host);
389         add_string(&authentication,
390                    "serviceDescription",
391                    ui->service_description);
392         add_string(&authentication, "authDescription", ui->auth_description);
393         add_string(&authentication, "clientDomain", ui->client.domain_name);
394         add_string(&authentication, "clientAccount", ui->client.account_name);
395         add_string(&authentication, "workstation", ui->workstation_name);
396         add_string(&authentication, "becameAccount", account_name);
397         add_string(&authentication, "becameDomain", domain_name);
398         add_sid(&authentication, "becameSid", sid);
399         add_string(&authentication, "mappedAccount", ui->mapped.account_name);
400         add_string(&authentication, "mappedDomain", ui->mapped.domain_name);
401         add_string(&authentication,
402                    "netlogonComputer",
403                    ui->netlogon_trust_account.computer_name);
404         add_string(&authentication,
405                    "netlogonTrustAccount",
406                    ui->netlogon_trust_account.account_name);
407         snprintf(negotiate_flags,
408                  sizeof( negotiate_flags),
409                  "0x%08X",
410                  ui->netlogon_trust_account.negotiate_flags);
411         add_string(&authentication, "netlogonNegotiateFlags", negotiate_flags);
412         add_int(&authentication,
413                 "netlogonSecureChannelType",
414                 ui->netlogon_trust_account.secure_channel_type);
415         add_sid(&authentication,
416                 "netlogonTrustAccountSid",
417                 ui->netlogon_trust_account.sid);
418         add_string(&authentication, "passwordType", get_password_type( ui));
419         add_object(&context,AUTH_JSON_TYPE, &authentication);
420
421         log_json(&context, AUTH_JSON_TYPE, DBGC_AUTH_AUDIT, debug_level);
422         free_json_context(&context);
423 }
424
425 /*
426  * Log details of a successful authorization to a service,
427  * in a machine parsable json format
428  *
429  * IF removing or changing the format/meaning of a field please update the
430  *    major version number AUTHZ_MAJOR
431  *
432  * IF adding a new field please update the minor version number AUTHZ_MINOR
433  *
434  *  To process the resulting log lines from the commend line use jq to
435  *  parse the json.
436  *
437  *  grep "JSON Authentication" log_file |\
438  *  sed "s;^[^{]*;;" |\
439  *  jq -rc '"\(.timestamp)\t
440  *           \(.Authorization.domain)\t
441  *           \(.Authorization.account)\t
442  *           \(.Authorization.remoteAddress)"'
443  *
444  */
445 static void log_successful_authz_event_json(
446                                 const struct tsocket_address *remote,
447                                 const struct tsocket_address *local,
448                                 const char *service_description,
449                                 const char *auth_type,
450                                 const char *transport_protection,
451                                 struct auth_session_info *session_info,
452                                 int debug_level)
453 {
454         struct json_context context = get_json_context();
455         struct json_context authorization;
456         char account_flags[11];
457
458         //start_object(&context, NULL);
459         add_timestamp(&context);
460         add_string(&context, "type", AUTHZ_JSON_TYPE);
461         authorization = get_json_context();
462         add_version(&authorization, AUTHZ_MAJOR, AUTHZ_MINOR);
463         add_address(&authorization, "localAddress", local);
464         add_address(&authorization, "remoteAddress", remote);
465         add_string(&authorization, "serviceDescription", service_description);
466         add_string(&authorization, "authType", auth_type);
467         add_string(&authorization, "domain", session_info->info->domain_name);
468         add_string(&authorization, "account", session_info->info->account_name);
469         add_sid(&authorization, "sid", &session_info->security_token->sids[0]);
470         add_string(&authorization,
471                    "logonServer",
472                    session_info->info->logon_server);
473         add_string(&authorization, "transportProtection", transport_protection);
474
475         snprintf(account_flags,
476                  sizeof( account_flags),
477                  "0x%08X",
478                  session_info->info->acct_flags);
479         add_string(&authorization, "accountFlags", account_flags);
480         add_object(&context,AUTHZ_JSON_TYPE, &authorization);
481
482         log_json(&context,
483                  AUTHZ_JSON_TYPE,
484                  DBGC_AUTH_AUDIT,
485                  debug_level);
486         free_json_context(&context);
487 }
488
489 #else
490
491 static void log_authentication_event_json(
492                         const struct auth_usersupplied_info *ui,
493                         NTSTATUS status,
494                         const char *domain_name,
495                         const char *account_name,
496                         const char *unix_username,
497                         struct dom_sid *sid,
498                         int debug_level)
499 {
500         return;
501 }
502
503 static void log_successful_authz_event_json(
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         return;
513 }
514
515 #endif
516
517 /*
518  * Determine the type of the password supplied for the
519  * authorisation attempt.
520  *
521  */
522 static const char* get_password_type(const struct auth_usersupplied_info *ui)
523 {
524
525         const char *password_type = NULL;
526
527         if (ui->password_state == AUTH_PASSWORD_RESPONSE &&
528             (ui->logon_parameters & MSV1_0_ALLOW_MSVCHAPV2) &&
529             ui->password.response.nt.length == 24) {
530                 password_type = "MSCHAPv2";
531         } else if ((ui->logon_parameters & MSV1_0_CLEARTEXT_PASSWORD_SUPPLIED)
532                    || (ui->password_state == AUTH_PASSWORD_PLAIN)) {
533                 password_type = "Plaintext";
534         } else if (ui->password_state == AUTH_PASSWORD_HASH) {
535                 password_type = "Supplied-NT-Hash";
536         } else if (ui->password_state == AUTH_PASSWORD_RESPONSE
537                    && ui->password.response.nt.length > 24) {
538                 password_type = "NTLMv2";
539         } else if (ui->password_state == AUTH_PASSWORD_RESPONSE
540                    && ui->password.response.nt.length == 24) {
541                 password_type = "NTLMv1";
542         } else if (ui->password_state == AUTH_PASSWORD_RESPONSE
543                    && ui->password.response.lanman.length == 24) {
544                 password_type = "LANMan";
545         } else if (ui->password_state == AUTH_PASSWORD_RESPONSE
546                    && ui->password.response.nt.length == 0
547                    && ui->password.response.lanman.length == 0) {
548                 password_type = "No-Password";
549         }
550         return password_type;
551 }
552
553 /*
554  * Write a human readable authentication log entry.
555  *
556  */
557 static void log_authentication_event_human_readable(
558                         const struct auth_usersupplied_info *ui,
559                         NTSTATUS status,
560                         const char *domain_name,
561                         const char *account_name,
562                         const char *unix_username,
563                         struct dom_sid *sid,
564                         int debug_level)
565 {
566         TALLOC_CTX *frame = NULL;
567
568         const char *ts = NULL;             /* formatted current time      */
569         char *remote = NULL;               /* formatted remote host       */
570         char *local = NULL;                /* formatted local host        */
571         char *nl = NULL;                   /* NETLOGON details if present */
572         char *trust_computer_name = NULL;
573         char *trust_account_name = NULL;
574         char *logon_line = NULL;
575         const char *password_type = NULL;
576
577         frame = talloc_stackframe();
578
579         password_type = get_password_type( ui);
580         /* Get the current time */
581         ts = get_timestamp(frame);
582
583         /* Only log the NETLOGON details if they are present */
584         if (ui->netlogon_trust_account.computer_name ||
585             ui->netlogon_trust_account.account_name) {
586                 trust_computer_name = log_escape(frame,
587                         ui->netlogon_trust_account.computer_name);
588                 trust_account_name  = log_escape(frame,
589                         ui->netlogon_trust_account.account_name);
590                 nl = talloc_asprintf(frame,
591                         " NETLOGON computer [%s] trust account [%s]",
592                         trust_computer_name, trust_account_name);
593         }
594
595         remote = tsocket_address_string(ui->remote_host, frame);
596         local  = tsocket_address_string(ui->local_host, frame);
597
598         if (NT_STATUS_IS_OK(status)) {
599                 char sid_buf[DOM_SID_STR_BUFLEN];
600
601                 dom_sid_string_buf(sid, sid_buf, sizeof(sid_buf));
602                 logon_line = talloc_asprintf(frame,
603                                              " became [%s]\\[%s] [%s].",
604                                              log_escape(frame, domain_name),
605                                              log_escape(frame, account_name),
606                                              sid_buf);
607         } else {
608                 logon_line = talloc_asprintf(
609                                 frame,
610                                 " mapped to [%s]\\[%s].",
611                                 log_escape(frame, ui->mapped.domain_name),
612                                 log_escape(frame, ui->mapped.account_name));
613         }
614
615         DEBUGC( DBGC_AUTH_AUDIT, debug_level, (
616                 "Auth: [%s,%s] user [%s]\\[%s]"
617                 " at [%s] with [%s] status [%s]"
618                 " workstation [%s] remote host [%s]"
619                 "%s local host [%s]"
620                 " %s\n",
621                 ui->service_description,
622                 ui->auth_description,
623                 log_escape(frame, ui->client.domain_name),
624                 log_escape(frame, ui->client.account_name),
625                 ts,
626                 password_type,
627                 nt_errstr( status),
628                 log_escape(frame, ui->workstation_name),
629                 remote,
630                 logon_line,
631                 local,
632                 nl ? nl : ""
633                 ));
634
635         talloc_free(frame);
636 }
637
638 /*
639  * Log details of an authentication attempt.
640  * Successful and unsuccessful attempts are logged.
641  *
642  * NOTE: msg_ctx and lp_ctx is optional, but when supplied allows streaming the
643  * authentication events over the message bus.
644  */
645 void log_authentication_event( const struct auth_usersupplied_info *ui,
646                               NTSTATUS status,
647                               const char *domain_name,
648                               const char *account_name,
649                               const char *unix_username,
650                               struct dom_sid *sid)
651 {
652         /* set the log level */
653         int debug_level = AUTH_FAILURE_LEVEL;
654
655         if (NT_STATUS_IS_OK(status)) {
656                 debug_level = AUTH_SUCCESS_LEVEL;
657                 if (dom_sid_equal(sid, &global_sid_Anonymous)) {
658                         debug_level = AUTH_ANONYMOUS_LEVEL;
659                 }
660         }
661
662         if (CHECK_DEBUGLVLC( DBGC_AUTH_AUDIT, debug_level)) {
663                 log_authentication_event_human_readable(ui,
664                                                         status,
665                                                         domain_name,
666                                                         account_name,
667                                                         unix_username,
668                                                         sid,
669                                                         debug_level);
670         }
671         if (CHECK_DEBUGLVLC( DBGC_AUTH_AUDIT_JSON, debug_level)) {
672                 log_authentication_event_json(ui,
673                                               status,
674                                               domain_name,
675                                               account_name,
676                                               unix_username,
677                                               sid,
678                                               debug_level);
679         }
680 }
681
682
683
684 /*
685  * Log details of a successful authorization to a service,
686  * in a human readable format.
687  *
688  */
689 static void log_successful_authz_event_human_readable(
690                                 const struct tsocket_address *remote,
691                                 const struct tsocket_address *local,
692                                 const char *service_description,
693                                 const char *auth_type,
694                                 const char *transport_protection,
695                                 struct auth_session_info *session_info,
696                                 int debug_level)
697 {
698         TALLOC_CTX *frame = NULL;
699
700         const char *ts = NULL;       /* formatted current time      */
701         char *remote_str = NULL;     /* formatted remote host       */
702         char *local_str = NULL;      /* formatted local host        */
703         char sid_buf[DOM_SID_STR_BUFLEN];
704
705         frame = talloc_stackframe();
706
707         /* Get the current time */
708         ts = get_timestamp(frame);
709
710         remote_str = tsocket_address_string(remote, frame);
711         local_str  = tsocket_address_string(local, frame);
712
713         dom_sid_string_buf(&session_info->security_token->sids[0],
714                            sid_buf,
715                            sizeof(sid_buf));
716
717         DEBUGC( DBGC_AUTH_AUDIT, debug_level, (
718                 "Successful AuthZ: [%s,%s] user [%s]\\[%s] [%s]"
719                 " at [%s]"
720                 " Remote host [%s]"
721                 " local host [%s]\n",
722                 service_description,
723                 auth_type,
724                 log_escape(frame, session_info->info->domain_name),
725                 log_escape(frame, session_info->info->account_name),
726                 sid_buf,
727                 ts,
728                 remote_str,
729                 local_str));
730
731         talloc_free(frame);
732 }
733
734 /*
735  * Log details of a successful authorization to a service.
736  *
737  * Only successful authorizations are logged.  For clarity:
738  * - NTLM bad passwords will be recorded by log_authentication_event
739  * - Kerberos decrypt failures need to be logged in gensec_gssapi et al
740  *
741  * The service may later refuse authorization due to an ACL.
742  *
743  * NOTE: msg_ctx and lp_ctx is optional, but when supplied allows streaming the
744  * authentication events over the message bus.
745  */
746 void log_successful_authz_event(const struct tsocket_address *remote,
747                                 const struct tsocket_address *local,
748                                 const char *service_description,
749                                 const char *auth_type,
750                                 const char *transport_protection,
751                                 struct auth_session_info *session_info)
752 {
753         int debug_level = AUTHZ_SUCCESS_LEVEL;
754
755         /* set the log level */
756         if (security_token_is_anonymous(session_info->security_token)) {
757                 debug_level = AUTH_ANONYMOUS_LEVEL;
758         }
759
760         if (CHECK_DEBUGLVLC( DBGC_AUTH_AUDIT, debug_level)) {
761                 log_successful_authz_event_human_readable(remote,
762                                                           local,
763                                                           service_description,
764                                                           auth_type,
765                                                           transport_protection,
766                                                           session_info,
767                                                           debug_level);
768         }
769         if (CHECK_DEBUGLVLC( DBGC_AUTH_AUDIT_JSON, debug_level)) {
770                 log_successful_authz_event_json(remote,
771                                                 local,
772                                                 service_description,
773                                                 auth_type,
774                                                 transport_protection,
775                                                 session_info,
776                                                 debug_level);
777         }
778 }