Add support for "{ptype}" trace format specifier
[krb5.git] / src / lib / krb5 / os / trace.c
index 3f31ea920dcd1a0d449563d9cda50ef9a8c29193..f3e1d8954d8f8623760c7e13a7509801d47c0ec4 100644 (file)
@@ -1,7 +1,6 @@
-/* -*- mode: c; indent-tabs-mode: nil -*- */
+/* -*- mode: c; c-basic-offset: 4; indent-tabs-mode: nil -*- */
+/* lib/krb5/os/trace.c - krb5int_trace implementation */
 /*
- * lib/krb5/krb/trace.c
- *
  * Copyright 2009 by the Massachusetts Institute of Technology.
  * All Rights Reserved.
  *
@@ -9,7 +8,7 @@
  *   require a specific license from the United States Government.
  *   It is the responsibility of any person or organization contemplating
  *   export to obtain such a license before exporting.
- * 
+ *
  * WITHIN THAT CONSTRAINT, permission to use, copy, modify, and
  * distribute this software and its documentation for any purpose and
  * without fee is hereby granted, provided that the above copyright
  * M.I.T. makes no representations about the suitability of
  * this software for any purpose.  It is provided "as is" without express
  * or implied warranty.
- *
- * k5trace implementation
  */
 
-/* k5trace is defined in k5-int.h as a macro or static inline function,
- * and is called like so:
+/*
+ * krb5int_trace is defined in k5-trace.h as a macro or static inline
+ * function, and is called like so:
  *
- *   void k5trace(krb5_context context, const char *fmt, ...)
+ *   void krb5int_trace(krb5_context context, const char *fmt, ...)
  *
  * Arguments may or may not be evaluated, so don't pass argument
  * expressions with side effects.  Tracing support and calls can be
@@ -40,6 +38,7 @@
  */
 
 #include "k5-int.h"
+#include "cm.h"
 
 #ifndef DISABLE_TRACING
 
@@ -64,6 +63,27 @@ hash_bytes(krb5_context context, const void *ptr, size_t len)
     return s;
 }
 
+static char *
+principal_type_string(krb5_int32 type)
+{
+    switch (type) {
+    case KRB5_NT_UNKNOWN: return "unknown";
+    case KRB5_NT_PRINCIPAL: return "principal";
+    case KRB5_NT_SRV_INST: return "service instance";
+    case KRB5_NT_SRV_HST: return "service with host as instance";
+    case KRB5_NT_SRV_XHST: return "service with host as components";
+    case KRB5_NT_UID: return "unique ID";
+    case KRB5_NT_X500_PRINCIPAL: return "X.509";
+    case KRB5_NT_SMTP_NAME: return "SMTP email";
+    case KRB5_NT_ENTERPRISE_PRINCIPAL: return "Windows 2000 UPN";
+    case KRB5_NT_WELLKNOWN: return "well-known";
+    case KRB5_NT_MS_PRINCIPAL: return "Windows 2000 UPN and SID";
+    case KRB5_NT_MS_PRINCIPAL_AND_ID: return "NT 4 style name";
+    case KRB5_NT_ENT_PRINCIPAL_AND_ID: return "NT 4 style name and SID";
+    default: return "?";
+    }
+}
+
 static char *
 trace_format(krb5_context context, const char *fmt, va_list ap)
 {
@@ -71,7 +91,7 @@ trace_format(krb5_context context, const char *fmt, va_list ap)
     krb5_error_code kerr;
     size_t len, i;
     int err;
-    struct addrinfo *ai;
+    struct conn_state *cs;
     const krb5_data *d;
     krb5_data data;
     char addrbuf[NI_MAXHOST], portbuf[NI_MAXSERV], tmpbuf[200], *str;
@@ -107,18 +127,18 @@ trace_format(krb5_context context, const char *fmt, va_list ap)
         } else if (strcmp(tmpbuf, "long") == 0) {
             krb5int_buf_add_fmt(&buf, "%ld", va_arg(ap, long));
         } else if (strcmp(tmpbuf, "str") == 0) {
-           p = va_arg(ap, const char *);
-           krb5int_buf_add(&buf, (p == NULL) ? "(null)" : p);
+            p = va_arg(ap, const char *);
+            krb5int_buf_add(&buf, (p == NULL) ? "(null)" : p);
         } else if (strcmp(tmpbuf, "lenstr") == 0) {
             len = va_arg(ap, size_t);
-           p = va_arg(ap, const char *);
+            p = va_arg(ap, const char *);
             if (p == NULL && len != 0)
                 krb5int_buf_add(&buf, "(null)");
             else
                 krb5int_buf_add_len(&buf, p, len);
         } else if (strcmp(tmpbuf, "hexlenstr") == 0) {
             len = va_arg(ap, size_t);
-           p = va_arg(ap, const char *);
+            p = va_arg(ap, const char *);
             if (p == NULL && len != 0)
                 krb5int_buf_add(&buf, "(null)");
             else {
@@ -127,7 +147,7 @@ trace_format(krb5_context context, const char *fmt, va_list ap)
             }
         } else if (strcmp(tmpbuf, "hashlenstr") == 0) {
             len = va_arg(ap, size_t);
-           p = va_arg(ap, const char *);
+            p = va_arg(ap, const char *);
             if (p == NULL && len != 0)
                 krb5int_buf_add(&buf, "(null)");
             else {
@@ -136,51 +156,51 @@ trace_format(krb5_context context, const char *fmt, va_list ap)
                     krb5int_buf_add(&buf, str);
                 free(str);
             }
-        } else if (strcmp(tmpbuf, "addrinfo") == 0) {
-           ai = va_arg(ap, struct addrinfo *);
-           if (ai->ai_socktype == SOCK_DGRAM)
-               krb5int_buf_add(&buf, "dgram");
-           else if (ai->ai_socktype == SOCK_STREAM)
-               krb5int_buf_add(&buf, "stream");
-           else
-               krb5int_buf_add_fmt(&buf, "socktype%d", ai->ai_socktype);
+        } else if (strcmp(tmpbuf, "connstate") == 0) {
+            cs = va_arg(ap, struct conn_state *);
+            if (cs->socktype == SOCK_DGRAM)
+                krb5int_buf_add(&buf, "dgram");
+            else if (cs->socktype == SOCK_STREAM)
+                krb5int_buf_add(&buf, "stream");
+            else
+                krb5int_buf_add_fmt(&buf, "socktype%d", cs->socktype);
 
-           if (getnameinfo(ai->ai_addr, ai->ai_addrlen,
+            if (getnameinfo((struct sockaddr *)&cs->addr, cs->addrlen,
                             addrbuf, sizeof(addrbuf), portbuf, sizeof(portbuf),
                             NI_NUMERICHOST|NI_NUMERICSERV) != 0) {
-               if (ai->ai_addr->sa_family == AF_UNSPEC)
-                   krb5int_buf_add(&buf, " AF_UNSPEC");
-               else
-                   krb5int_buf_add_fmt(&buf, " af%d", ai->ai_addr->sa_family);
-           } else
-               krb5int_buf_add_fmt(&buf, " %s:%s", addrbuf, portbuf);
+                if (cs->family == AF_UNSPEC)
+                    krb5int_buf_add(&buf, " AF_UNSPEC");
+                else
+                    krb5int_buf_add_fmt(&buf, " af%d", cs->family);
+            } else
+                krb5int_buf_add_fmt(&buf, " %s:%s", addrbuf, portbuf);
         } else if (strcmp(tmpbuf, "data") == 0) {
-           d = va_arg(ap, krb5_data *);
+            d = va_arg(ap, krb5_data *);
             if (d == NULL || (d->length != 0 && d->data == NULL))
                 krb5int_buf_add(&buf, "(null)");
             else
                 krb5int_buf_add_len(&buf, d->data, d->length);
         } else if (strcmp(tmpbuf, "hexdata") == 0) {
-           d = va_arg(ap, krb5_data *);
+            d = va_arg(ap, krb5_data *);
             if (d == NULL)
                 krb5int_buf_add(&buf, "(null)");
             else
                 subfmt(context, &buf, "{hexlenstr}", d->length, d->data);
         } else if (strcmp(tmpbuf, "errno") == 0) {
-           err = va_arg(ap, int);
-           p = NULL;
+            err = va_arg(ap, int);
+            p = NULL;
 #ifdef HAVE_STRERROR_R
-           if (strerror_r(err, tmpbuf, sizeof(tmpbuf)) == 0)
-               p = tmpbuf;
+            if (strerror_r(err, tmpbuf, sizeof(tmpbuf)) == 0)
+                p = tmpbuf;
 #endif
-           if (p == NULL)
-               p = strerror(err);
+            if (p == NULL)
+                p = strerror(err);
             krb5int_buf_add_fmt(&buf, "%d/%s", err, p);
         } else if (strcmp(tmpbuf, "kerr") == 0) {
-           kerr = va_arg(ap, krb5_error_code);
+            kerr = va_arg(ap, krb5_error_code);
             p = krb5_get_error_message(context, kerr);
             krb5int_buf_add_fmt(&buf, "%ld/%s", (long) kerr,
-                                (kerr == 0) ? "success" : p);
+                                kerr ? p : "Success");
             krb5_free_error_message(context, p);
         } else if (strcmp(tmpbuf, "keyblock") == 0) {
             keyblock = va_arg(ap, const krb5_keyblock *);
@@ -194,7 +214,7 @@ trace_format(krb5_context context, const char *fmt, va_list ap)
         } else if (strcmp(tmpbuf, "key") == 0) {
             key = va_arg(ap, krb5_key);
             if (key == NULL)
-                krb5int_buf_add(&buf, "(null");
+                krb5int_buf_add(&buf, "(null)");
             else
                 subfmt(context, &buf, "{keyblock}", &key->keyblock);
         } else if (strcmp(tmpbuf, "cksum") == 0) {
@@ -208,6 +228,9 @@ trace_format(krb5_context context, const char *fmt, va_list ap)
                 krb5int_buf_add(&buf, str);
                 krb5_free_unparsed_name(context, str);
             }
+        } else if (strcmp(tmpbuf, "ptype") == 0) {
+            p = principal_type_string(va_arg(ap, krb5_int32));
+            krb5int_buf_add(&buf, p);
         } else if (strcmp(tmpbuf, "patypes") == 0) {
             padata = va_arg(ap, krb5_pa_data **);
             if (padata == NULL || *padata == NULL)
@@ -226,7 +249,7 @@ trace_format(krb5_context context, const char *fmt, va_list ap)
         } else if (strcmp(tmpbuf, "etypes") == 0) {
             etypes = va_arg(ap, krb5_enctype *);
             if (etypes == NULL || *etypes == 0)
-                krb5int_buf_add(&buf, "(empty");
+                krb5int_buf_add(&buf, "(empty)");
             for (; etypes != NULL && *etypes != 0; etypes++) {
                 subfmt(context, &buf, "{etype}", *etypes);
                 if (*(etypes + 1) != 0)
@@ -315,13 +338,14 @@ krb5_set_trace_callback(krb5_context context, krb5_trace_callback fn,
     return 0;
 }
 
-static void
+static void KRB5_CALLCONV
 file_trace_cb(krb5_context context, const struct krb5_trace_info *info, void *data)
 {
     int *fd = data;
 
     if (info == NULL) {
         /* Null info means destroy the callback data. */
+        close(*fd);
         free(fd);
         return;
     }