1 /* -*- mode: c; c-basic-offset: 4; indent-tabs-mode: nil -*- */ 2 /* kdc/kdc_log.c - Logging functions for KDC requests */ 3 /* 4 * Copyright 2008,2009 by the Massachusetts Institute of Technology. 5 * All Rights Reserved. 6 * 7 * Export of this software from the United States of America may 8 * require a specific license from the United States Government. 9 * It is the responsibility of any person or organization contemplating 10 * export to obtain such a license before exporting. 11 * 12 * WITHIN THAT CONSTRAINT, permission to use, copy, modify, and 13 * distribute this software and its documentation for any purpose and 14 * without fee is hereby granted, provided that the above copyright 15 * notice appear in all copies and that both that copyright notice and 16 * this permission notice appear in supporting documentation, and that 17 * the name of M.I.T. not be used in advertising or publicity pertaining 18 * to distribution of the software without specific, written prior 19 * permission. Furthermore if you modify this software you must label 20 * your software as modified software and not distribute it in such a 21 * fashion that it might be confused with the original M.I.T. software. 22 * M.I.T. makes no representations about the suitability of 23 * this software for any purpose. It is provided "as is" without express 24 * or implied warranty. 25 */ 26 27 #include "k5-int.h" 28 #include "kdc_util.h" 29 #include <syslog.h> 30 #include "adm_proto.h" 31 32 /* 33 * A note on KDC-status string format. 34 * 35 * - All letters in the status string should be capitalized; 36 * - the words in the status phrase are separated by underscores; 37 * - abbreviations should be avoided. Some acceptable "standard" acronyms 38 * are AS_REQ, TGS_REP etc. 39 * - since in almost all cases KDC status string is set on error, no need 40 * to state this fact as part of the status string; 41 * - KDC status string should be an imperative phrase. 42 * 43 * Example: "MAKE_RANDOM_KEY" 44 */ 45 46 /* Main logging routines for ticket requests. 47 48 There are a few simple cases -- unparseable requests mainly -- 49 where messages are logged otherwise, but once a ticket request can 50 be decoded in some basic way, these routines are used for logging 51 the details. */ 52 53 /* "status" is null to indicate success. */ 54 /* Someday, pass local address/port as well. */ 55 /* Currently no info about name canonicalization is logged. */ 56 void 57 log_as_req(krb5_context context, 58 const struct sockaddr *local_addr, 59 const struct sockaddr *remote_addr, 60 krb5_kdc_req *request, krb5_kdc_rep *reply, 61 krb5_db_entry *client, const char *cname, 62 krb5_db_entry *server, const char *sname, 63 krb5_timestamp authtime, 64 const char *status, krb5_error_code errcode, const char *emsg) 65 { 66 char fromstring[128]; 67 char *ktypestr = NULL; 68 const char *cname2 = cname ? cname : "<unknown client>"; 69 const char *sname2 = sname ? sname : "<unknown server>"; 70 krb5_address laddr = { 0 }, raddr = { 0 }; 71 72 k5_print_addr(remote_addr, fromstring, sizeof(fromstring)); 73 74 ktypestr = ktypes2str(request->ktype, request->nktypes); 75 76 if (status == NULL) { 77 /* success */ 78 char *rep_etypestr = rep_etypes2str(reply); 79 krb5_klog_syslog(LOG_INFO, _("AS_REQ (%s) %s: ISSUE: authtime %u, %s, " 80 "%s for %s"), 81 ktypestr ? ktypestr : "", fromstring, 82 (unsigned int)authtime, 83 rep_etypestr ? rep_etypestr : "", cname2, sname2); 84 free(rep_etypestr); 85 } else { 86 /* fail */ 87 krb5_klog_syslog(LOG_INFO, _("AS_REQ (%s) %s: %s: %s for %s%s%s"), 88 ktypestr ? ktypestr : "", fromstring, status, cname2, 89 sname2, emsg ? ", " : "", emsg ? emsg : ""); 90 } 91 (void)k5_sockaddr_to_address(local_addr, TRUE, &laddr); 92 (void)k5_sockaddr_to_address(remote_addr, TRUE, &raddr); 93 krb5_db_audit_as_req(context, request, &laddr, &raddr, client, server, 94 authtime, errcode); 95 96 free(ktypestr); 97 } 98 99 /* 100 * Unparse a principal for logging purposes and limit the string length. 101 * Ignore errors because the most likely errors are memory exhaustion, and many 102 * other things will fail in the logging functions in that case. 103 */ 104 static void 105 unparse_and_limit(krb5_context ctx, krb5_principal princ, char **str) 106 { 107 /* Ignore errors */ 108 krb5_unparse_name(ctx, princ, str); 109 limit_string(*str); 110 } 111 112 /* Here "status" must be non-null. Error code 113 KRB5KDC_ERR_SERVER_NOMATCH is handled specially. 114 115 Currently no info about name canonicalization is logged. */ 116 void 117 log_tgs_req(krb5_context ctx, const struct sockaddr *from, 118 krb5_kdc_req *request, krb5_kdc_rep *reply, 119 krb5_principal cprinc, krb5_principal sprinc, 120 krb5_principal altcprinc, 121 krb5_timestamp authtime, 122 unsigned int c_flags, 123 const char *status, krb5_error_code errcode, const char *emsg) 124 { 125 char *ktypestr = NULL, *rep_etypestr = NULL; 126 char fromstring[128]; 127 char *cname = NULL, *sname = NULL, *altcname = NULL; 128 char *logcname = NULL, *logsname = NULL, *logaltcname = NULL; 129 130 k5_print_addr(from, fromstring, sizeof(fromstring)); 131 132 unparse_and_limit(ctx, cprinc, &cname); 133 logcname = (cname != NULL) ? cname : "<unknown client>"; 134 unparse_and_limit(ctx, sprinc, &sname); 135 logsname = (sname != NULL) ? sname : "<unknown server>"; 136 unparse_and_limit(ctx, altcprinc, &altcname); 137 logaltcname = (altcname != NULL) ? altcname : "<unknown>"; 138 139 /* Differences: server-nomatch message logs 2nd ticket's client 140 name (useful), and doesn't log ktypestr (probably not 141 important). */ 142 if (errcode != KRB5KDC_ERR_SERVER_NOMATCH) { 143 ktypestr = ktypes2str(request->ktype, request->nktypes); 144 if (reply != NULL) 145 rep_etypestr = rep_etypes2str(reply); 146 krb5_klog_syslog(LOG_INFO, _("TGS_REQ (%s) %s: %s: authtime %u, %s%s " 147 "%s for %s%s%s"), 148 ktypestr ? ktypestr : "", fromstring, status, 149 (unsigned int)authtime, 150 rep_etypestr ? rep_etypestr : "", 151 !errcode ? "," : "", logcname, logsname, 152 errcode ? ", " : "", errcode ? emsg : ""); 153 if (isflagset(c_flags, KRB5_KDB_FLAG_PROTOCOL_TRANSITION)) 154 krb5_klog_syslog(LOG_INFO, 155 _("... PROTOCOL-TRANSITION s4u-client=%s"), 156 logaltcname); 157 else if (isflagset(c_flags, KRB5_KDB_FLAG_CONSTRAINED_DELEGATION)) 158 krb5_klog_syslog(LOG_INFO, 159 _("... CONSTRAINED-DELEGATION s4u-client=%s"), 160 logaltcname); 161 162 } else 163 krb5_klog_syslog(LOG_INFO, _("TGS_REQ %s: %s: authtime %u, %s for %s, " 164 "2nd tkt client %s"), 165 fromstring, status, (unsigned int)authtime, 166 logcname, logsname, logaltcname); 167 168 free(rep_etypestr); 169 free(ktypestr); 170 krb5_free_unparsed_name(ctx, cname); 171 krb5_free_unparsed_name(ctx, sname); 172 krb5_free_unparsed_name(ctx, altcname); 173 } 174 175 void 176 log_tgs_badtrans(krb5_context ctx, krb5_principal cprinc, 177 krb5_principal sprinc, krb5_data *trcont, 178 krb5_error_code errcode) 179 { 180 unsigned int tlen; 181 char *tdots; 182 const char *emsg = NULL; 183 char *cname = NULL, *sname = NULL; 184 char *logcname = NULL, *logsname = NULL; 185 186 unparse_and_limit(ctx, cprinc, &cname); 187 logcname = (cname != NULL) ? cname : "<unknown client>"; 188 unparse_and_limit(ctx, sprinc, &sname); 189 logsname = (sname != NULL) ? sname : "<unknown server>"; 190 191 tlen = trcont->length; 192 tdots = tlen > 125 ? "..." : ""; 193 tlen = tlen > 125 ? 125 : tlen; 194 195 if (errcode == KRB5KRB_AP_ERR_ILL_CR_TKT) 196 krb5_klog_syslog(LOG_INFO, _("bad realm transit path from '%s' " 197 "to '%s' via '%.*s%s'"), 198 logcname, logsname, tlen, 199 trcont->data, tdots); 200 else { 201 emsg = krb5_get_error_message(ctx, errcode); 202 krb5_klog_syslog(LOG_ERR, _("unexpected error checking transit " 203 "from '%s' to '%s' via '%.*s%s': %s"), 204 logcname, logsname, tlen, 205 trcont->data, tdots, 206 emsg); 207 krb5_free_error_message(ctx, emsg); 208 emsg = NULL; 209 } 210 krb5_free_unparsed_name(ctx, cname); 211 krb5_free_unparsed_name(ctx, sname); 212 } 213 214 void 215 log_tgs_alt_tgt(krb5_context context, krb5_principal p) 216 { 217 char *sname; 218 if (krb5_unparse_name(context, p, &sname)) { 219 krb5_klog_syslog(LOG_INFO, 220 _("TGS_REQ: issuing alternate <un-unparsable> TGT")); 221 } else { 222 limit_string(sname); 223 krb5_klog_syslog(LOG_INFO, _("TGS_REQ: issuing TGT %s"), sname); 224 free(sname); 225 } 226 /* OpenSolaris: audit_krb5kdc_tgs_req_alt_tgt(...) */ 227 } 228