smbd: Fix "reset on zero vc"
[npower/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 0
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
61 /*
62  * Get a human readable timestamp.
63  *
64  * Returns the current time formatted as
65  *  "Tue, 14 Mar 2017 08:38:42.209028 NZDT"
66  *
67  * The returned string is allocated by talloc in the supplied context.
68  * It is the callers responsibility to free it.
69  *
70  */
71 static const char* get_timestamp(TALLOC_CTX *frame)
72 {
73         char buffer[40];        /* formatted time less usec and timezone */
74         char tz[10];            /* formatted time zone                   */
75         struct tm* tm_info;     /* current local time                    */
76         struct timeval tv;      /* current system time                   */
77         int r;                  /* response code from gettimeofday       */
78         const char * ts;        /* formatted time stamp                  */
79
80         r = gettimeofday(&tv, NULL);
81         if (r) {
82                 DBG_ERR("Unable to get time of day: (%d) %s\n",
83                         errno,
84                         strerror(errno));
85                 return NULL;
86         }
87
88         tm_info = localtime(&tv.tv_sec);
89         if (tm_info == NULL) {
90                 DBG_ERR("Unable to determine local time\n");
91                 return NULL;
92         }
93
94         strftime(buffer, sizeof(buffer)-1, "%a, %d %b %Y %H:%M:%S", tm_info);
95         strftime(tz, sizeof(tz)-1, "%Z", tm_info);
96         ts = talloc_asprintf(frame, "%s.%06ld %s", buffer, tv.tv_usec, tz);
97         if (ts == NULL) {
98                 DBG_ERR("Out of memory formatting time stamp\n");
99         }
100         return ts;
101 }
102
103 /*
104  * Determine the type of the password supplied for the
105  * authorisation attempt.
106  *
107  */
108 static const char* get_password_type(const struct auth_usersupplied_info *ui);
109
110 #ifdef HAVE_JANSSON
111
112 #include <jansson.h>
113 #include "system/time.h"
114
115 /*
116  * Context required by the JSON generation
117  *  routines
118  *
119  */
120 struct json_context {
121         json_t *root;
122         bool error;
123 };
124
125 static NTSTATUS get_auth_event_server(struct imessaging_context *msg_ctx,
126                                       struct server_id *auth_event_server)
127 {
128         NTSTATUS status;
129         TALLOC_CTX *frame = talloc_stackframe();
130         unsigned num_servers, i;
131         struct server_id *servers;
132
133         status = irpc_servers_byname(msg_ctx, frame,
134                                      AUTH_EVENT_NAME,
135                                      &num_servers, &servers);
136
137         if (!NT_STATUS_IS_OK(status)) {
138                 DBG_NOTICE("Failed to find 'auth_event' registered on the "
139                            "message bus to send JSON authentication events to: %s\n",
140                            nt_errstr(status));
141                 TALLOC_FREE(frame);
142                 return status;
143         }
144
145         /*
146          * Select the first server that is listening, because
147          * we get connection refused as
148          * NT_STATUS_OBJECT_NAME_NOT_FOUND without waiting
149          */
150         for (i = 0; i < num_servers; i++) {
151                 status = imessaging_send(msg_ctx, servers[i], MSG_PING,
152                                          &data_blob_null);
153                 if (NT_STATUS_IS_OK(status)) {
154                         *auth_event_server = servers[i];
155                         TALLOC_FREE(frame);
156                         return NT_STATUS_OK;
157                 }
158         }
159         DBG_NOTICE("Failed to find a running 'auth_event' server "
160                    "registered on the message bus to send JSON "
161                    "authentication events to\n");
162         TALLOC_FREE(frame);
163         return NT_STATUS_OBJECT_NAME_NOT_FOUND;
164 }
165
166 static void auth_message_send(struct imessaging_context *msg_ctx,
167                               const char *json)
168 {
169         struct server_id auth_event_server;
170         NTSTATUS status;
171         DATA_BLOB json_blob = data_blob_string_const(json);
172         if (msg_ctx == NULL) {
173                 return;
174         }
175
176         /* Need to refetch the address each time as the destination server may
177          * have disconnected and reconnected in the interim, in which case
178          * messages may get lost, manifests in the auth_log tests
179          */
180         status = get_auth_event_server(msg_ctx, &auth_event_server);
181         if (!NT_STATUS_IS_OK(status)) {
182                 return;
183         }
184
185         status = imessaging_send(msg_ctx, auth_event_server, MSG_AUTH_LOG,
186                                  &json_blob);
187
188         /* If the server crashed, try to find it again */
189         if (NT_STATUS_EQUAL(status, NT_STATUS_OBJECT_NAME_NOT_FOUND)) {
190                 status = get_auth_event_server(msg_ctx, &auth_event_server);
191                 if (!NT_STATUS_IS_OK(status)) {
192                         return;
193                 }
194                 imessaging_send(msg_ctx, auth_event_server, MSG_AUTH_LOG,
195                                 &json_blob);
196
197         }
198 }
199
200 /*
201  * Write the json object to the debug logs.
202  *
203  */
204 static void log_json(struct imessaging_context *msg_ctx,
205                      struct loadparm_context *lp_ctx,
206                      struct json_context *context,
207                      const char *type, int debug_class, int debug_level)
208 {
209         char* json = NULL;
210
211         if (context->error) {
212                 return;
213         }
214
215         json = json_dumps(context->root, 0);
216         if (json == NULL) {
217                 DBG_ERR("Unable to convert JSON object to string\n");
218                 context->error = true;
219                 return;
220         }
221
222         DEBUGC(debug_class, debug_level, ("JSON %s: %s\n", type, json));
223         if (msg_ctx && lp_ctx && lpcfg_auth_event_notification(lp_ctx)) {
224                 auth_message_send(msg_ctx, json);
225         }
226
227         if (json) {
228                 free(json);
229         }
230
231 }
232
233 /*
234  * Create a new json logging context.
235  *
236  * Free with a call to free_json_context
237  *
238  */
239 static struct json_context get_json_context(void) {
240
241         struct json_context context;
242         context.error = false;
243
244         context.root = json_object();
245         if (context.root == NULL) {
246                 context.error = true;
247                 DBG_ERR("Unable to create json_object\n");
248         }
249         return context;
250 }
251
252 /*
253  * free a previously created json_context
254  *
255  */
256 static void free_json_context(struct json_context *context)
257 {
258         if (context->root) {
259                 json_decref(context->root);
260         }
261 }
262
263 /*
264  * Output a JSON pair with name name and integer value value
265  *
266  */
267 static void add_int(struct json_context *context,
268                     const char* name,
269                     const int value)
270 {
271         int rc = 0;
272
273         if (context->error) {
274                 return;
275         }
276
277         rc = json_object_set_new(context->root, name, json_integer(value));
278         if (rc) {
279                 DBG_ERR("Unable to set name [%s] value [%d]\n", name, value);
280                 context->error = true;
281         }
282
283 }
284
285 /*
286  * Output a JSON pair with name name and string value value
287  *
288  */
289 static void add_string(struct json_context *context,
290                        const char* name,
291                        const char* value)
292 {
293         int rc = 0;
294
295         if (context->error) {
296                 return;
297         }
298
299         if (value) {
300                 rc = json_object_set_new(context->root, name, json_string(value));
301         } else {
302                 rc = json_object_set_new(context->root, name, json_null());
303         }
304         if (rc) {
305                 DBG_ERR("Unable to set name [%s] value [%s]\n", name, value);
306                 context->error = true;
307         }
308 }
309
310
311 /*
312  * Output a JSON pair with name name and object value
313  *
314  */
315 static void add_object(struct json_context *context,
316                        const char* name,
317                        struct json_context *value)
318 {
319         int rc = 0;
320
321         if (value->error) {
322                 context->error = true;
323         }
324         if (context->error) {
325                 return;
326         }
327         rc = json_object_set_new(context->root, name, value->root);
328         if (rc) {
329                 DBG_ERR("Unable to add object [%s]\n", name);
330                 context->error = true;
331         }
332 }
333
334 /*
335  * Output a version object
336  *
337  * "version":{"major":1,"minor":0}
338  *
339  */
340 static void add_version(struct json_context *context, int major, int minor)
341 {
342         struct json_context version = get_json_context();
343         add_int(&version, "major", major);
344         add_int(&version, "minor", minor);
345         add_object(context, "version", &version);
346 }
347
348 /*
349  * Output the current date and time as a timestamp in ISO 8601 format
350  *
351  * "timestamp":"2017-03-06T17:18:04.455081+1300"
352  *
353  */
354 static void add_timestamp(struct json_context *context)
355 {
356         char buffer[40];        /* formatted time less usec and timezone */
357         char timestamp[50];     /* the formatted ISO 8601 time stamp     */
358         char tz[10];            /* formatted time zone                   */
359         struct tm* tm_info;     /* current local time                    */
360         struct timeval tv;      /* current system time                   */
361         int r;                  /* response code from gettimeofday       */
362
363         if (context->error) {
364                 return;
365         }
366
367         r = gettimeofday(&tv, NULL);
368         if (r) {
369                 DBG_ERR("Unable to get time of day: (%d) %s\n",
370                         errno,
371                         strerror(errno));
372                 context->error = true;
373                 return;
374         }
375
376         tm_info = localtime(&tv.tv_sec);
377         if (tm_info == NULL) {
378                 DBG_ERR("Unable to determine local time\n");
379                 context->error = true;
380                 return;
381         }
382
383         strftime(buffer, sizeof(buffer)-1, "%Y-%m-%dT%T", tm_info);
384         strftime(tz, sizeof(tz)-1, "%z", tm_info);
385         snprintf(timestamp, sizeof(timestamp),"%s.%06ld%s",
386                  buffer, tv.tv_usec, tz);
387         add_string(context,"timestamp", timestamp);
388 }
389
390
391 /*
392  * Output an address pair, with name name.
393  *
394  * "localAddress":"ipv6::::0"
395  *
396  */
397 static void add_address(struct json_context *context,
398                         const char *name,
399                         const struct tsocket_address *address)
400 {
401         char *s = NULL;
402         TALLOC_CTX *frame = talloc_stackframe();
403
404         if (context->error) {
405                 return;
406         }
407
408         s = tsocket_address_string(address, frame);
409         add_string(context, name, s);
410         talloc_free(frame);
411
412 }
413
414 /*
415  * Output a SID with name name
416  *
417  * "sid":"S-1-5-18"
418  *
419  */
420 static void add_sid(struct json_context *context,
421                     const char *name,
422                     const struct dom_sid *sid)
423 {
424         char sid_buf[DOM_SID_STR_BUFLEN];
425
426         if (context->error) {
427                 return;
428         }
429
430         dom_sid_string_buf(sid, sid_buf, sizeof(sid_buf));
431         add_string(context, name, sid_buf);
432 }
433
434 /*
435  * Add a formatted string representation of a GUID to a json object.
436  *
437  */
438 static void add_guid(struct json_context *context,
439                      const char *name,
440                      struct GUID *guid)
441 {
442
443         char *guid_str;
444         struct GUID_txt_buf guid_buff;
445
446         if (context->error) {
447                 return;
448         }
449
450         guid_str = GUID_buf_string(guid, &guid_buff);
451         add_string(context, name, guid_str);
452 }
453
454 /*
455  * Write a machine parsable json formatted authentication log entry.
456  *
457  * IF removing or changing the format/meaning of a field please update the
458  *    major version number AUTH_MAJOR
459  *
460  * IF adding a new field please update the minor version number AUTH_MINOR
461  *
462  *  To process the resulting log lines from the commend line use jq to
463  *  parse the json.
464  *
465  *  grep "JSON Authentication" log file |
466  *  sed 's;^[^{]*;;' |
467  * jq -rc  '"\(.timestamp)\t\(.Authentication.status)\t
468  *           \(.Authentication.clientDomain)\t
469  *           \(.Authentication.clientAccount)
470  *           \t\(.Authentication.workstation)
471  *           \t\(.Authentication.remoteAddress)
472  *           \t\(.Authentication.localAddress)"'
473  */
474 static void log_authentication_event_json(
475                         struct imessaging_context *msg_ctx,
476                         struct loadparm_context *lp_ctx,
477                         const struct auth_usersupplied_info *ui,
478                         NTSTATUS status,
479                         const char *domain_name,
480                         const char *account_name,
481                         const char *unix_username,
482                         struct dom_sid *sid,
483                         int debug_level)
484 {
485         struct json_context context = get_json_context();
486         struct json_context authentication;
487         char negotiate_flags[11];
488
489         add_timestamp(&context);
490         add_string(&context, "type", AUTH_JSON_TYPE);
491
492         authentication = get_json_context();
493         add_version(&authentication, AUTH_MAJOR, AUTH_MINOR);
494         add_string(&authentication, "status", nt_errstr(status));
495         add_address(&authentication, "localAddress", ui->local_host);
496         add_address(&authentication, "remoteAddress", ui->remote_host);
497         add_string(&authentication,
498                    "serviceDescription",
499                    ui->service_description);
500         add_string(&authentication, "authDescription", ui->auth_description);
501         add_string(&authentication, "clientDomain", ui->client.domain_name);
502         add_string(&authentication, "clientAccount", ui->client.account_name);
503         add_string(&authentication, "workstation", ui->workstation_name);
504         add_string(&authentication, "becameAccount", account_name);
505         add_string(&authentication, "becameDomain", domain_name);
506         add_sid(&authentication, "becameSid", sid);
507         add_string(&authentication, "mappedAccount", ui->mapped.account_name);
508         add_string(&authentication, "mappedDomain", ui->mapped.domain_name);
509         add_string(&authentication,
510                    "netlogonComputer",
511                    ui->netlogon_trust_account.computer_name);
512         add_string(&authentication,
513                    "netlogonTrustAccount",
514                    ui->netlogon_trust_account.account_name);
515         snprintf(negotiate_flags,
516                  sizeof( negotiate_flags),
517                  "0x%08X",
518                  ui->netlogon_trust_account.negotiate_flags);
519         add_string(&authentication, "netlogonNegotiateFlags", negotiate_flags);
520         add_int(&authentication,
521                 "netlogonSecureChannelType",
522                 ui->netlogon_trust_account.secure_channel_type);
523         add_sid(&authentication,
524                 "netlogonTrustAccountSid",
525                 ui->netlogon_trust_account.sid);
526         add_string(&authentication, "passwordType", get_password_type(ui));
527         add_object(&context,AUTH_JSON_TYPE, &authentication);
528
529         log_json(msg_ctx,
530                  lp_ctx,
531                  &context,
532                  AUTH_JSON_TYPE,
533                  DBGC_AUTH_AUDIT,
534                  debug_level);
535         free_json_context(&context);
536 }
537
538 /*
539  * Log details of a successful authorization to a service,
540  * in a machine parsable json format
541  *
542  * IF removing or changing the format/meaning of a field please update the
543  *    major version number AUTHZ_MAJOR
544  *
545  * IF adding a new field please update the minor version number AUTHZ_MINOR
546  *
547  *  To process the resulting log lines from the commend line use jq to
548  *  parse the json.
549  *
550  *  grep "JSON Authentication" log_file |\
551  *  sed "s;^[^{]*;;" |\
552  *  jq -rc '"\(.timestamp)\t
553  *           \(.Authorization.domain)\t
554  *           \(.Authorization.account)\t
555  *           \(.Authorization.remoteAddress)"'
556  *
557  */
558 static void log_successful_authz_event_json(
559                                 struct imessaging_context *msg_ctx,
560                                 struct loadparm_context *lp_ctx,
561                                 const struct tsocket_address *remote,
562                                 const struct tsocket_address *local,
563                                 const char *service_description,
564                                 const char *auth_type,
565                                 const char *transport_protection,
566                                 struct auth_session_info *session_info,
567                                 int debug_level)
568 {
569         struct json_context context = get_json_context();
570         struct json_context authorization;
571         char account_flags[11];
572
573         //start_object(&context, NULL);
574         add_timestamp(&context);
575         add_string(&context, "type", AUTHZ_JSON_TYPE);
576         authorization = get_json_context();
577         add_version(&authorization, AUTHZ_MAJOR, AUTHZ_MINOR);
578         add_address(&authorization, "localAddress", local);
579         add_address(&authorization, "remoteAddress", remote);
580         add_string(&authorization, "serviceDescription", service_description);
581         add_string(&authorization, "authType", auth_type);
582         add_string(&authorization, "domain", session_info->info->domain_name);
583         add_string(&authorization, "account", session_info->info->account_name);
584         add_sid(&authorization, "sid", &session_info->security_token->sids[0]);
585         add_guid(&authorization,
586                  "sessionId",
587                  &session_info->unique_session_token);
588         add_string(&authorization,
589                    "logonServer",
590                    session_info->info->logon_server);
591         add_string(&authorization, "transportProtection", transport_protection);
592
593         snprintf(account_flags,
594                  sizeof(account_flags),
595                  "0x%08X",
596                  session_info->info->acct_flags);
597         add_string(&authorization, "accountFlags", account_flags);
598         add_object(&context,AUTHZ_JSON_TYPE, &authorization);
599
600         log_json(msg_ctx,
601                  lp_ctx,
602                  &context,
603                  AUTHZ_JSON_TYPE,
604                  DBGC_AUTH_AUDIT,
605                  debug_level);
606         free_json_context(&context);
607 }
608
609 #else
610
611 static void log_no_json(struct imessaging_context *msg_ctx,
612                         struct loadparm_context *lp_ctx)
613 {
614         if (msg_ctx && lp_ctx && lpcfg_auth_event_notification(lp_ctx)) {
615                 static bool auth_event_logged = false;
616                 if (auth_event_logged == false) {
617                         auth_event_logged = true;
618                         DBG_ERR("auth event notification = true but Samba was not compiled with jansson\n");
619                 }
620         } else {
621                 static bool json_logged = false;
622                 if (json_logged == false) {
623                         json_logged = true;
624                         DBG_NOTICE("JSON auth logs not available unless compiled with jansson\n");
625                 }
626         }
627
628         return;
629 }
630
631 static void log_authentication_event_json(
632                         struct imessaging_context *msg_ctx,
633                         struct loadparm_context *lp_ctx,
634                         const struct auth_usersupplied_info *ui,
635                         NTSTATUS status,
636                         const char *domain_name,
637                         const char *account_name,
638                         const char *unix_username,
639                         struct dom_sid *sid,
640                         int debug_level)
641 {
642         log_no_json(msg_ctx, lp_ctx);
643         return;
644 }
645
646 static void log_successful_authz_event_json(
647                                 struct imessaging_context *msg_ctx,
648                                 struct loadparm_context *lp_ctx,
649                                 const struct tsocket_address *remote,
650                                 const struct tsocket_address *local,
651                                 const char *service_description,
652                                 const char *auth_type,
653                                 const char *transport_protection,
654                                 struct auth_session_info *session_info,
655                                 int debug_level)
656 {
657         log_no_json(msg_ctx, lp_ctx);
658         return;
659 }
660
661 #endif
662
663 /*
664  * Determine the type of the password supplied for the
665  * authorisation attempt.
666  *
667  */
668 static const char* get_password_type(const struct auth_usersupplied_info *ui)
669 {
670
671         const char *password_type = NULL;
672
673         if (ui->password_type != NULL) {
674                 password_type = ui->password_type;
675         } else if (ui->auth_description != NULL &&
676                    strncmp("ServerAuthenticate", ui->auth_description, 18) == 0)
677         {
678                 if (ui->netlogon_trust_account.negotiate_flags
679                     & NETLOGON_NEG_SUPPORTS_AES) {
680                         password_type = "HMAC-SHA256";
681                 } else if (ui->netlogon_trust_account.negotiate_flags
682                            & NETLOGON_NEG_STRONG_KEYS) {
683                         password_type = "HMAC-MD5";
684                 } else {
685                         password_type = "DES";
686                 }
687         } else if (ui->password_state == AUTH_PASSWORD_RESPONSE &&
688                    (ui->logon_parameters & MSV1_0_ALLOW_MSVCHAPV2) &&
689                    ui->password.response.nt.length == 24) {
690                 password_type = "MSCHAPv2";
691         } else if ((ui->logon_parameters & MSV1_0_CLEARTEXT_PASSWORD_SUPPLIED)
692                    || (ui->password_state == AUTH_PASSWORD_PLAIN)) {
693                 password_type = "Plaintext";
694         } else if (ui->password_state == AUTH_PASSWORD_HASH) {
695                 password_type = "Supplied-NT-Hash";
696         } else if (ui->password_state == AUTH_PASSWORD_RESPONSE
697                    && ui->password.response.nt.length > 24) {
698                 password_type = "NTLMv2";
699         } else if (ui->password_state == AUTH_PASSWORD_RESPONSE
700                    && ui->password.response.nt.length == 24) {
701                 password_type = "NTLMv1";
702         } else if (ui->password_state == AUTH_PASSWORD_RESPONSE
703                    && ui->password.response.lanman.length == 24) {
704                 password_type = "LANMan";
705         } else if (ui->password_state == AUTH_PASSWORD_RESPONSE
706                    && ui->password.response.nt.length == 0
707                    && ui->password.response.lanman.length == 0) {
708                 password_type = "No-Password";
709         }
710         return password_type;
711 }
712
713 /*
714  * Write a human readable authentication log entry.
715  *
716  */
717 static void log_authentication_event_human_readable(
718                         const struct auth_usersupplied_info *ui,
719                         NTSTATUS status,
720                         const char *domain_name,
721                         const char *account_name,
722                         const char *unix_username,
723                         struct dom_sid *sid,
724                         int debug_level)
725 {
726         TALLOC_CTX *frame = NULL;
727
728         const char *ts = NULL;             /* formatted current time      */
729         char *remote = NULL;               /* formatted remote host       */
730         char *local = NULL;                /* formatted local host        */
731         char *nl = NULL;                   /* NETLOGON details if present */
732         char *trust_computer_name = NULL;
733         char *trust_account_name = NULL;
734         char *logon_line = NULL;
735         const char *password_type = NULL;
736
737         frame = talloc_stackframe();
738
739         password_type = get_password_type(ui);
740         /* Get the current time */
741         ts = get_timestamp(frame);
742
743         /* Only log the NETLOGON details if they are present */
744         if (ui->netlogon_trust_account.computer_name ||
745             ui->netlogon_trust_account.account_name) {
746                 trust_computer_name = log_escape(frame,
747                         ui->netlogon_trust_account.computer_name);
748                 trust_account_name  = log_escape(frame,
749                         ui->netlogon_trust_account.account_name);
750                 nl = talloc_asprintf(frame,
751                         " NETLOGON computer [%s] trust account [%s]",
752                         trust_computer_name, trust_account_name);
753         }
754
755         remote = tsocket_address_string(ui->remote_host, frame);
756         local = tsocket_address_string(ui->local_host, frame);
757
758         if (NT_STATUS_IS_OK(status)) {
759                 char sid_buf[DOM_SID_STR_BUFLEN];
760
761                 dom_sid_string_buf(sid, sid_buf, sizeof(sid_buf));
762                 logon_line = talloc_asprintf(frame,
763                                              " became [%s]\\[%s] [%s].",
764                                              log_escape(frame, domain_name),
765                                              log_escape(frame, account_name),
766                                              sid_buf);
767         } else {
768                 logon_line = talloc_asprintf(
769                                 frame,
770                                 " mapped to [%s]\\[%s].",
771                                 log_escape(frame, ui->mapped.domain_name),
772                                 log_escape(frame, ui->mapped.account_name));
773         }
774
775         DEBUGC(DBGC_AUTH_AUDIT, debug_level,
776                ("Auth: [%s,%s] user [%s]\\[%s]"
777                 " at [%s] with [%s] status [%s]"
778                 " workstation [%s] remote host [%s]"
779                 "%s local host [%s]"
780                 " %s\n",
781                 ui->service_description,
782                 ui->auth_description,
783                 log_escape(frame, ui->client.domain_name),
784                 log_escape(frame, ui->client.account_name),
785                 ts,
786                 password_type,
787                 nt_errstr(status),
788                 log_escape(frame, ui->workstation_name),
789                 remote,
790                 logon_line,
791                 local,
792                 nl ? nl : ""
793                ));
794
795         talloc_free(frame);
796 }
797
798 /*
799  * Log details of an authentication attempt.
800  * Successful and unsuccessful attempts are logged.
801  *
802  * NOTE: msg_ctx and lp_ctx is optional, but when supplied allows streaming the
803  * authentication events over the message bus.
804  */
805 void log_authentication_event(struct imessaging_context *msg_ctx,
806                               struct loadparm_context *lp_ctx,
807                               const struct auth_usersupplied_info *ui,
808                               NTSTATUS status,
809                               const char *domain_name,
810                               const char *account_name,
811                               const char *unix_username,
812                               struct dom_sid *sid)
813 {
814         /* set the log level */
815         int debug_level = AUTH_FAILURE_LEVEL;
816
817         if (NT_STATUS_IS_OK(status)) {
818                 debug_level = AUTH_SUCCESS_LEVEL;
819                 if (dom_sid_equal(sid, &global_sid_Anonymous)) {
820                         debug_level = AUTH_ANONYMOUS_LEVEL;
821                 }
822         }
823
824         if (CHECK_DEBUGLVLC(DBGC_AUTH_AUDIT, debug_level)) {
825                 log_authentication_event_human_readable(ui,
826                                                         status,
827                                                         domain_name,
828                                                         account_name,
829                                                         unix_username,
830                                                         sid,
831                                                         debug_level);
832         }
833         if (CHECK_DEBUGLVLC(DBGC_AUTH_AUDIT_JSON, debug_level) ||
834             (msg_ctx && lp_ctx && lpcfg_auth_event_notification(lp_ctx))) {
835                 log_authentication_event_json(msg_ctx, lp_ctx,
836                                               ui,
837                                               status,
838                                               domain_name,
839                                               account_name,
840                                               unix_username,
841                                               sid,
842                                               debug_level);
843         }
844 }
845
846
847
848 /*
849  * Log details of a successful authorization to a service,
850  * in a human readable format.
851  *
852  */
853 static void log_successful_authz_event_human_readable(
854                                 const struct tsocket_address *remote,
855                                 const struct tsocket_address *local,
856                                 const char *service_description,
857                                 const char *auth_type,
858                                 const char *transport_protection,
859                                 struct auth_session_info *session_info,
860                                 int debug_level)
861 {
862         TALLOC_CTX *frame = NULL;
863
864         const char *ts = NULL;       /* formatted current time      */
865         char *remote_str = NULL;     /* formatted remote host       */
866         char *local_str = NULL;      /* formatted local host        */
867         char sid_buf[DOM_SID_STR_BUFLEN];
868
869         frame = talloc_stackframe();
870
871         /* Get the current time */
872         ts = get_timestamp(frame);
873
874         remote_str = tsocket_address_string(remote, frame);
875         local_str = tsocket_address_string(local, frame);
876
877         dom_sid_string_buf(&session_info->security_token->sids[0],
878                            sid_buf,
879                            sizeof(sid_buf));
880
881         DEBUGC(DBGC_AUTH_AUDIT, debug_level,
882                ("Successful AuthZ: [%s,%s] user [%s]\\[%s] [%s]"
883                 " at [%s]"
884                 " Remote host [%s]"
885                 " local host [%s]\n",
886                 service_description,
887                 auth_type,
888                 log_escape(frame, session_info->info->domain_name),
889                 log_escape(frame, session_info->info->account_name),
890                 sid_buf,
891                 ts,
892                 remote_str,
893                 local_str));
894
895         talloc_free(frame);
896 }
897
898 /*
899  * Log details of a successful authorization to a service.
900  *
901  * Only successful authorizations are logged.  For clarity:
902  * - NTLM bad passwords will be recorded by log_authentication_event
903  * - Kerberos decrypt failures need to be logged in gensec_gssapi et al
904  *
905  * The service may later refuse authorization due to an ACL.
906  *
907  * NOTE: msg_ctx and lp_ctx is optional, but when supplied allows streaming the
908  * authentication events over the message bus.
909  */
910 void log_successful_authz_event(struct imessaging_context *msg_ctx,
911                                 struct loadparm_context *lp_ctx,
912                                 const struct tsocket_address *remote,
913                                 const struct tsocket_address *local,
914                                 const char *service_description,
915                                 const char *auth_type,
916                                 const char *transport_protection,
917                                 struct auth_session_info *session_info)
918 {
919         int debug_level = AUTHZ_SUCCESS_LEVEL;
920
921         /* set the log level */
922         if (security_token_is_anonymous(session_info->security_token)) {
923                 debug_level = AUTH_ANONYMOUS_LEVEL;
924         }
925
926         if (CHECK_DEBUGLVLC(DBGC_AUTH_AUDIT, debug_level)) {
927                 log_successful_authz_event_human_readable(remote,
928                                                           local,
929                                                           service_description,
930                                                           auth_type,
931                                                           transport_protection,
932                                                           session_info,
933                                                           debug_level);
934         }
935         if (CHECK_DEBUGLVLC(DBGC_AUTH_AUDIT_JSON, debug_level) ||
936             (msg_ctx && lp_ctx && lpcfg_auth_event_notification(lp_ctx))) {
937                 log_successful_authz_event_json(msg_ctx, lp_ctx,
938                                                 remote,
939                                                 local,
940                                                 service_description,
941                                                 auth_type,
942                                                 transport_protection,
943                                                 session_info,
944                                                 debug_level);
945         }
946 }