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