Moved most string-type conversion routines from libkadm to libkrb5 to
authorRichard Basch <probe@mit.edu>
Tue, 5 Dec 1995 03:24:44 +0000 (03:24 +0000)
committerRichard Basch <probe@mit.edu>
Tue, 5 Dec 1995 03:24:44 +0000 (03:24 +0000)
reduce the dependencies on libkadm and for better support of multiple
encryption type lookup in krb5.conf.

git-svn-id: svn://anonsvn.mit.edu/krb5/trunk@7159 dc483132-0cff-0310-8789-dd5450dbe970

src/lib/kadm/str_conv.c
src/lib/krb5/krb/Makefile.in
src/lib/krb5/krb/str_conv.c [new file with mode: 0644]

index 9bfdee10a709b8579e3af55bad0e087c6d7ba960..fc99674932c0b61be77a3862d1fd883b758ca37d 100644 (file)
  *
  * String decoding:
  * ----------------
- * krb5_string_to_enctype()    - Convert string to krb5_enctype.
- * krb5_string_to_salttype()   - Convert string to salttype (krb5_int32)
- * krb5_string_to_enctype()    - Convert string to krb5_enctype.
- * krb5_string_to_cksumtype()  - Convert string to krb5_cksumtype;
  * krb5_string_to_flags()      - Convert string to krb5_flags.
- * krb5_string_to_timestamp()  - Convert string to krb5_timestamp.
- * krb5_string_to_deltat()     - Convert string to krb5_deltat.
  *
  * String encoding:
  * ----------------
- * krb5_enctype_to_string()    - Convert krb5_enctype to string.
- * krb5_salttype_to_string()   - Convert salttype (krb5_int32) to string.
- * krb5_enctype_to_string()    - Convert krb5_enctype to string.
- * krb5_cksumtype_to_string()  - Convert krb5_cksumtype to string.
  * krb5_flags_to_string()      - Convert krb5_flags to string.
- * krb5_timestamp_to_string()  - Convert krb5_timestamp to string.
- * krb5_timestamp_to_sfstring()        - Convert krb5_timestamp to short filled string
- * krb5_deltat_to_string()     - Convert krb5_deltat to string.
  */
 
 #include "k5-int.h"
 /*
  * Local data structures.
  */
-struct enctype_lookup_entry {
-    krb5_enctype       ktt_enctype;            /* Keytype              */
-    const char *       ktt_specifier;          /* How to recognize it  */
-    const char *       ktt_output;             /* How to spit it out   */
-};
-
-struct salttype_lookup_entry {
-    krb5_int32         stt_enctype;            /* Salt type            */
-    const char *       stt_specifier;          /* How to recognize it  */
-    const char *       stt_output;             /* How to spit it out   */
-};
-
-struct cksumtype_lookup_entry {
-    krb5_cksumtype     cst_cksumtype;          /* Checksum type        */
-    const char *       cst_specifier;          /* How to recognize it  */
-    const char *       cst_output;             /* How to spit it out   */
-};
-
 struct flags_lookup_entry {
     krb5_flags         fl_flags;               /* Flag                 */
     krb5_boolean       fl_sense;               /* Sense of the flag    */
@@ -83,60 +52,11 @@ struct flags_lookup_entry {
     const char *       fl_output;              /* How to spit it out   */
 };
 
-struct deltat_match_entry {
-    const char *       dt_scan_format;         /* sscanf format        */
-    int                        dt_nmatch;              /* Number to match      */
-    int                        dt_dindex;              /* Day index            */
-    int                        dt_hindex;              /* Hour index           */
-    int                        dt_mindex;              /* Minute index         */
-    int                        dt_sindex;              /* Second index         */
-};
-
 /*
  * Local strings
  */
 
 /* Keytype strings */
-static const char enctype_des_in[]             = "des";
-static const char enctype_null_in[]            = "null";
-static const char enctype_descbccrc_in[]       = "des-cbc-crc";
-static const char enctype_descbcmd4_in[]       = "des-cbc-md4";
-static const char enctype_descbcmd5_in[]       = "des-cbc-md5";
-static const char enctype_des3cbcmd5_in[]      = "des3-cbc-md5";
-static const char enctype_descbcraw_in[]       = "des-cbc-raw";
-static const char enctype_null_out[]           = "Null";
-static const char enctype_descbccrc_out[]      = "DES cbc mode with CRC-32";
-static const char enctype_descbcmd4_out[]      = "DES cbc mode with RSA-MD4";
-static const char enctype_descbcmd5_out[]      = "DES cbc mode with RSA-MD5";
-static const char enctype_des3cbcmd5_out[]     = "Triple DES cbc mode with RSA-MD5";
-static const char enctype_descbcraw_out[]      = "DES cbc mode raw";
-
-/* Salttype strings */
-static const char stype_v5_in[]                = "normal";
-static const char stype_v4_in[]                = "v4";
-static const char stype_norealm_in[]   = "norealm";
-static const char stype_olrealm_in[]   = "onlyrealm";
-static const char stype_special_in[]   = "special";
-static const char stype_v5_out[]       = "Version 5";
-static const char stype_v4_out[]       = "Version 4";
-static const char stype_norealm_out[]  = "Version 5 - No Realm";
-static const char stype_olrealm_out[]  = "Version 5 - Realm Only";
-static const char stype_special_out[]  = "Special";
-
-/* Checksum type strings */
-static const char cstype_crc32_in[]    = "crc32";
-static const char cstype_md4_in[]      = "md4";
-static const char cstype_md4des_in[]   = "md4-des";
-static const char cstype_descbc_in[]   = "des-cbc";
-static const char cstype_md5_in[]      = "md5";
-static const char cstype_md5des_in[]   = "md5-des";
-static const char cstype_crc32_out[]   = "CRC-32";
-static const char cstype_md4_out[]     = "RSA-MD4";
-static const char cstype_md4des_out[]  = "RSA-MD4 with DES cbc mode";
-static const char cstype_descbc_out[]  = "DES cbc mode";
-static const char cstype_md5_out[]     = "RSA-MD5";
-static const char cstype_md5des_out[]  = "RSA-MD5 with DES cbc mode";
-
 /* Flags strings */
 static const char flags_pdate_in[]     = "postdateable";
 static const char flags_fwd_in[]       = "forwardable";
@@ -167,95 +87,10 @@ static const char flags_md5_out[]  = "RSA-MD5 supported";
 static const char flags_default_neg[]  = "-";
 static const char flags_default_sep[]  = " ";
 
-/* Absolute time strings */
-static const char atime_full_digits[]  = "%y%m%d%H%M%S";
-static const char atime_full_digits_d[]        = "%y.%m.%d.%H.%M.%S";
-static const char atime_nsec_digits[]  = "%y%m%d%H%M";
-static const char atime_rel_hms[]      = "%H%M%S";
-static const char atime_rel_hm[]       = "%H%M";
-static const char atime_rel_col_hms[]  = "%T";
-static const char atime_rel_col_hm[]   = "%R";
-static const char atime_ldep_sfmt[]    = "%x:%X";
-static const char atime_full_text[]    = "%d-%b-%Y:%T";
-static const char atime_full_text_nos[]        = "%d-%b-%Y:%R";
-#if    !HAVE_STRPTIME
-static const char ascan_full_digits[]  = "%02d%02d%02d%02d%02d%02d";
-static const char ascan_full_digits_d[]        = "%02d.%02d.%02d.%02d.%02d.%02d";
-static const char ascan_nsec_digits[]  = "%02d%02d%02d%02d%02d";
-static const char ascan_rel_hms[]      = "%02d%02d%02d";
-static const char ascan_rel_hm[]       = "%02d%02d";
-static const char ascan_rel_col_hms[]  = "%02d:%02d:%02d";
-static const char ascan_rel_col_hm[]   = "%02d:%02d";
-#endif /* !HAVE_STRPTIME */
-#ifdef HAVE_STRFTIME
-static const char sftime_ldep_time[]   = "%c";
-static const char sftime_med_fmt[]     = "%d %b %y %T";
-static const char sftime_short_fmt[]   = "%x %X";
-static const char sftime_last_fmt[]    = "%d/%m/%y %R";
-#endif /* HAVE_STRFTIME */
-static const char sftime_default_fmt[] = "%02d/%02d/%02d %02d:%02d";
-static const size_t sftime_default_len = 2+1+2+1+2+1+2+1+2+1;
-
-/* Delta time strings */
-static const char dtscan_dhms_notext[] = "%d-%02d:%02d:%02d";
-static const char dtscan_dhms_stext[]  = "%dd%dh%dm%ds";
-static const char dtscan_hms_notext[]  = "%d:%02d:%02d";
-static const char dtscan_hms_stext[]   = "%dh%dm%ds";
-static const char dtscan_hm_notext[]   = "%d:%02d";
-static const char dtscan_hm_stext[]    = "%dh%dm";
-static const char dtscan_days[]                = "%d%[d]";
-static const char dtscan_hours[]       = "%d%[h]";
-static const char dtscan_minutes[]     = "%d%[m]";
-static const char dtscan_seconds[]     = "%d%[s]";
-static const char dt_day_singular[]    = "day";
-static const char dt_day_plural[]      = "days";
-static const char dt_output_donly[]    = "%d %s";
-static const char dt_output_dhms[]     = "%d %s %02d:%02d:%02d";
-static const char dt_output_hms[]      = "%d:%02d:%02d";
-
 /*
  * Lookup tables.
  */
 
-static const struct enctype_lookup_entry enctype_table[] = {
-/* krb5_enctype                input specifier         output string           */
-/*-------------                ----------------------- ------------------------*/
-{ ENCTYPE_NULL,                enctype_null_in,        enctype_null_out        },
-{ ENCTYPE_DES_CBC_MD5, enctype_des_in,         enctype_descbcmd5_out   },
-{ ENCTYPE_DES_CBC_CRC, enctype_descbccrc_in,   enctype_descbccrc_out   },
-{ ENCTYPE_DES_CBC_MD4, enctype_descbcmd4_in,   enctype_descbcmd4_out   },
-{ ENCTYPE_DES_CBC_MD5, enctype_descbcmd5_in,   enctype_descbcmd5_out   },
-{ ENCTYPE_DES3_CBC_MD5,        enctype_des3cbcmd5_in,  enctype_des3cbcmd5_out  },
-{ ENCTYPE_DES_CBC_RAW, enctype_descbcraw_in,   enctype_descbcraw_out   }
-};
-static const int enctype_table_nents = sizeof(enctype_table)/
-                                      sizeof(enctype_table[0]);
-
-static const struct salttype_lookup_entry salttype_table[] = {
-/* salt type                   input specifier         output string     */
-/*-----------------------------        ----------------------- ------------------*/
-{ KRB5_KDB_SALTTYPE_NORMAL,    stype_v5_in,            stype_v5_out      },
-{ KRB5_KDB_SALTTYPE_V4,                stype_v4_in,            stype_v4_out      },
-{ KRB5_KDB_SALTTYPE_NOREALM,   stype_norealm_in,       stype_norealm_out },
-{ KRB5_KDB_SALTTYPE_ONLYREALM, stype_olrealm_in,       stype_olrealm_out },
-{ KRB5_KDB_SALTTYPE_SPECIAL,   stype_special_in,       stype_special_out }
-};
-static const int salttype_table_nents = sizeof(salttype_table)/
-                                       sizeof(salttype_table[0]);
-
-static const struct cksumtype_lookup_entry cksumtype_table[] = {
-/* krb5_cksumtype         input specifier      output string           */
-/*----------------------- ---------------------        ------------------------*/
-{ CKSUMTYPE_CRC32,        cstype_crc32_in,     cstype_crc32_out        },
-{ CKSUMTYPE_RSA_MD4,      cstype_md4_in,       cstype_md4_out          },
-{ CKSUMTYPE_RSA_MD4_DES,  cstype_md4des_in,    cstype_md4des_out       },
-{ CKSUMTYPE_DESCBC,       cstype_descbc_in,    cstype_descbc_out       },
-{ CKSUMTYPE_RSA_MD5,      cstype_md5_in,       cstype_md5_out          },
-{ CKSUMTYPE_RSA_MD5_DES,  cstype_md5des_in,    cstype_md5des_out       }
-};
-static const int cksumtype_table_nents = sizeof(cksumtype_table)/
-                                        sizeof(cksumtype_table[0]);
-
 static const struct flags_lookup_entry flags_table[] = {
 /* flag                                sense   input specifier    output string     */
 /*----------------------------- -------        ------------------ ------------------*/
@@ -276,208 +111,7 @@ static const struct flags_lookup_entry flags_table[] = {
 static const int flags_table_nents = sizeof(flags_table)/
                                     sizeof(flags_table[0]);
 
-static const char * const atime_format_table[] = {
-atime_full_digits,     /* yymmddhhmmss                 */
-atime_full_digits_d,   /* yy.mm.dd.hh.mm.ss            */
-atime_nsec_digits,     /* yymmddhhmm                   */
-atime_rel_hms,         /* hhmmss                       */
-atime_rel_hm,          /* hhmm                         */
-atime_rel_col_hms,     /* hh:mm:ss                     */
-atime_rel_col_hm,      /* hh:mm                        */
-/* The following not really supported unless native strptime present */
-atime_ldep_sfmt,       /*locale-dependent short format */
-atime_full_text,       /* dd-month-yyyy:hh:mm:ss       */
-atime_full_text_nos    /* dd-month-yyyy:hh:mm          */
-};
-static const int atime_format_table_nents = sizeof(atime_format_table)/
-                                           sizeof(atime_format_table[0]);
-
-#ifdef HAVE_STRFTIME
-static const char * const sftime_format_table[] = {
-sftime_ldep_time,      /* Default locale-dependent date and time       */
-sftime_med_fmt,                /* dd mon yy hh:mm:ss                           */
-sftime_short_fmt,      /* locale-dependent short format                */
-sftime_last_fmt                /* dd/mm/yy hh:mm                               */
-};
-static const int sftime_format_table_nents = sizeof(sftime_format_table)/
-                                           sizeof(sftime_format_table[0]);
-#endif /* HAVE_STRFTIME */
-
-static const struct deltat_match_entry deltat_table[] = {
-/* scan format         nmatch  daypos  hourpos minpos  secpos  */
-/*---------------------        ------- ------- ------- ------- --------*/
-{ dtscan_dhms_notext,  4,      0,      1,      2,      3       },
-{ dtscan_dhms_stext,   4,      0,      1,      2,      3       },
-{ dtscan_hms_notext,   3,      -1,     0,      1,      2       },
-{ dtscan_hms_stext,    3,      -1,     0,      1,      2       },
-{ dtscan_hm_notext,    2,      -1,     -1,     0,      1       },
-{ dtscan_hm_stext,     2,      -1,     -1,     0,      1       },
-{ dtscan_days,         2,      0,      -1,     -1,     -1      },
-{ dtscan_hours,                2,      -1,     0,      -1,     -1      },
-{ dtscan_minutes,      2,      -1,     -1,     0,      -1      },
-{ dtscan_seconds,      2,      -1,     -1,     -1,     0       }
-};
-static const int deltat_table_nents = sizeof(deltat_table)/
-                                     sizeof(deltat_table[0]);
-\f
-#if    !HAVE_STRPTIME
-/*
- * Rudimentary version of strptime for systems which don't have it.
- */
-static char *
-strptime(buf, format, tm)
-    char *buf;
-    const char *format;
-    struct tm *tm;
-{
-    int year, month, day, hour, minute, second;
-    char *bp;
-    time_t now;
-    
-    /*
-     * We only understand the following fixed formats:
-     *    %y%m%d%H%M%S
-     *    %y.%m.%d.%H.%M.%S
-     *    %y%m%d%H%M
-     *    %H%M%S
-     *    %H%M
-     *    %T
-     *    %R
-     */
-    bp = (char *) NULL;
-    if (!strcmp(format, atime_full_digits) &&
-       (sscanf(buf, ascan_full_digits,
-               &year, &month, &day, &hour, &minute, &second) == 6)) {
-       tm->tm_year = year;
-       tm->tm_mon = month - 1;
-       tm->tm_mday = day;
-       tm->tm_hour = hour;
-       tm->tm_min = minute;
-       tm->tm_sec = second;
-       bp = &buf[strlen(atime_full_digits)];
-    }
-    else if (!strcmp(format,atime_full_digits_d) &&
-            (sscanf(buf, ascan_full_digits_d,
-                    &year, &month, &day, &hour, &minute, &second) == 6)) {
-       tm->tm_year = year;
-       tm->tm_mon = month - 1;
-       tm->tm_mday = day;
-       tm->tm_hour = hour;
-       tm->tm_min = minute;
-       tm->tm_sec = second;
-       bp = &buf[strlen(atime_full_digits_d)];
-    }
-    else if (!strcmp(format, atime_nsec_digits) &&
-            (sscanf(buf, ascan_nsec_digits,
-               &year, &month, &day, &hour, &minute) == 5)) {
-       tm->tm_year = year;
-       tm->tm_mon = month - 1;
-       tm->tm_mday = day;
-       tm->tm_hour = hour;
-       tm->tm_min = minute;
-       tm->tm_sec = 0;
-       bp = &buf[strlen(atime_nsec_digits)];
-    }
-    else if (!strcmp(format, atime_rel_hms) &&
-            (sscanf(buf, ascan_rel_hms, &hour, &minute, &second) == 3)) {
-       now = time((time_t *) NULL);
-       memcpy(tm, localtime(&now), sizeof(struct tm));
-       tm->tm_hour = hour;
-       tm->tm_min = minute;
-       tm->tm_sec = second;
-       bp = &buf[strlen(atime_rel_hms)];
-    }
-    else if (!strcmp(format, atime_rel_hm) &&
-            (sscanf(buf, ascan_rel_hm, &hour, &minute) == 2)) {
-       now = time((time_t *) NULL);
-       memcpy(tm, localtime(&now), sizeof(struct tm));
-       tm->tm_hour = hour;
-       tm->tm_min = minute;
-       bp = &buf[strlen(atime_rel_hm)];
-    }
-    else if (!strcmp(format, atime_rel_col_hms) &&
-            (sscanf(buf, ascan_rel_col_hms, &hour, &minute, &second) == 3)) {
-       now = time((time_t *) NULL);
-       memcpy(tm, localtime(&now), sizeof(struct tm));
-       tm->tm_hour = hour;
-       tm->tm_min = minute;
-       tm->tm_sec = second;
-       bp = &buf[strlen(atime_rel_col_hms)];
-    }
-    else if (!strcmp(format, atime_rel_col_hm) &&
-            (sscanf(buf, ascan_rel_col_hm, &hour, &minute) == 2)) {
-       now = time((time_t *) NULL);
-       memcpy(tm, localtime(&now), sizeof(struct tm));
-       tm->tm_hour = hour;
-       tm->tm_min = minute;
-       bp = &buf[strlen(atime_rel_col_hm)];
-    }
-    return(bp);
-}
-#endif /* HAVE_STRPTIME */
 \f
-/*
- * String to internal datatype routines.
- *
- * These routines return 0 for success, EINVAL for invalid entry.
- */
-krb5_error_code
-krb5_string_to_enctype(string, enctypep)
-    char               * string;
-    krb5_enctype       * enctypep;
-{
-    int i;
-    int found;
-
-    found = 0;
-    for (i=0; i<enctype_table_nents; i++) {
-       if (!strcasecmp(string, enctype_table[i].ktt_specifier)) {
-           found = 1;
-           *enctypep = enctype_table[i].ktt_enctype;
-           break;
-       }
-    }
-    return((found) ? 0 : EINVAL);
-}
-
-krb5_error_code
-krb5_string_to_salttype(string, salttypep)
-    char       * string;
-    krb5_int32 * salttypep;
-{
-    int i;
-    int found;
-
-    found = 0;
-    for (i=0; i<salttype_table_nents; i++) {
-       if (!strcasecmp(string, salttype_table[i].stt_specifier)) {
-           found = 1;
-           *salttypep = salttype_table[i].stt_enctype;
-           break;
-       }
-    }
-    return((found) ? 0 : EINVAL);
-}
-
-krb5_error_code
-krb5_string_to_cksumtype(string, cksumtypep)
-    char               * string;
-    krb5_cksumtype     * cksumtypep;
-{
-    int i;
-    int found;
-
-    found = 0;
-    for (i=0; i<cksumtype_table_nents; i++) {
-       if (!strcasecmp(string, cksumtype_table[i].cst_specifier)) {
-           found = 1;
-           *cksumtypep = cksumtype_table[i].cst_cksumtype;
-           break;
-       }
-    }
-    return((found) ? 0 : EINVAL);
-}
-
 krb5_error_code
 krb5_string_to_flags(string, positive, negative, flagsp)
     char       * string;
@@ -523,157 +157,6 @@ krb5_string_to_flags(string, positive, negative, flagsp)
     return((found) ? 0 : EINVAL);
 }
 
-krb5_error_code
-krb5_string_to_timestamp(string, timestampp)
-    char               * string;
-    krb5_timestamp     * timestampp;
-{
-    int i;
-    int found;
-    struct tm timebuf;
-
-    found = 0;
-    memset(&timebuf, 0, sizeof(timebuf));
-    for (i=0; i<atime_format_table_nents; i++) {
-       if (strptime(string, atime_format_table[i], &timebuf)) {
-           found = 1;
-           break;
-       }
-    }
-    if (found)
-       *timestampp = (krb5_timestamp) mktime(&timebuf);
-    return((found) ? 0 : EINVAL);
-}
-
-krb5_error_code
-krb5_string_to_deltat(string, deltatp)
-    char       * string;
-    krb5_deltat        * deltatp;
-{
-    int i;
-    int found;
-    int svalues[4];
-    int days, hours, minutes, seconds;
-    krb5_deltat        dt;
-
-    found = 0;
-    days = hours = minutes = seconds = 0;
-    for (i=0; i<deltat_table_nents; i++) {
-       if (sscanf(string, deltat_table[i].dt_scan_format,
-                  &svalues[0], &svalues[1], &svalues[2], &svalues[3]) ==
-           deltat_table[i].dt_nmatch) {
-           if (deltat_table[i].dt_dindex >= 0)
-               days = svalues[deltat_table[i].dt_dindex];
-           if (deltat_table[i].dt_hindex >= 0)
-               hours = svalues[deltat_table[i].dt_hindex];
-           if (deltat_table[i].dt_mindex >= 0)
-               minutes = svalues[deltat_table[i].dt_mindex];
-           if (deltat_table[i].dt_sindex >= 0)
-               seconds = svalues[deltat_table[i].dt_sindex];
-           found = 1;
-           break;
-       }
-    }
-    if (found) {
-       dt = days;
-       dt *= 24;
-       dt += hours;
-       dt *= 60;
-       dt += minutes;
-       dt *= 60;
-       dt += seconds;
-       *deltatp = dt;
-    }
-    return((found) ? 0 : EINVAL);
-}
-
-/*
- * Internal datatype to string routines.
- *
- * These routines return 0 for success, EINVAL for invalid parameter, ENOMEM
- * if the supplied buffer/length will not contain the output.
- */
-krb5_error_code
-krb5_enctype_to_string(enctype, buffer, buflen)
-    krb5_enctype       enctype;
-    char               * buffer;
-    size_t             buflen;
-{
-    int i;
-    const char *out;
-
-    out = (char *) NULL;
-    for (i=0; i<enctype_table_nents; i++) {
-       if (enctype ==  enctype_table[i].ktt_enctype) {
-           out = enctype_table[i].ktt_output;
-           break;
-       }
-    }
-    if (out) {
-       if (buflen > strlen(out))
-           strcpy(buffer, out);
-       else
-           out = (char *) NULL;
-       return((out) ? 0 : ENOMEM);
-    }
-    else
-       return(EINVAL);
-}
-
-krb5_error_code
-krb5_salttype_to_string(salttype, buffer, buflen)
-    krb5_int32 salttype;
-    char       * buffer;
-    size_t     buflen;
-{
-    int i;
-    const char *out;
-
-    out = (char *) NULL;
-    for (i=0; i<salttype_table_nents; i++) {
-       if (salttype ==  salttype_table[i].stt_enctype) {
-           out = salttype_table[i].stt_output;
-           break;
-       }
-    }
-    if (out) {
-       if (buflen > strlen(out))
-           strcpy(buffer, out);
-       else
-           out = (char *) NULL;
-       return((out) ? 0 : ENOMEM);
-    }
-    else
-       return(EINVAL);
-}
-
-krb5_error_code
-krb5_cksumtype_to_string(cksumtype, buffer, buflen)
-    krb5_cksumtype     cksumtype;
-    char               * buffer;
-    size_t             buflen;
-{
-    int i;
-    const char *out;
-
-    out = (char *) NULL;
-    for (i=0; i<cksumtype_table_nents; i++) {
-       if (cksumtype ==  cksumtype_table[i].cst_cksumtype) {
-           out = cksumtype_table[i].cst_output;
-           break;
-       }
-    }
-    if (out) {
-       if (buflen > strlen(out))
-           strcpy(buffer, out);
-       else
-           out = (char *) NULL;
-       return((out) ? 0 : ENOMEM);
-    }
-    else
-       return(EINVAL);
-}
-
 krb5_error_code
 krb5_flags_to_string(flags, sep, buffer, buflen)
     krb5_flags flags;
@@ -724,104 +207,3 @@ krb5_flags_to_string(flags, sep, buffer, buflen)
     }
     return(retval);
 }
-
-krb5_error_code
-krb5_timestamp_to_string(timestamp, buffer, buflen)
-    krb5_timestamp     timestamp;
-    char               * buffer;
-    size_t             buflen;
-{
-#if    HAVE_STRFTIME
-    if (strftime(buffer, buflen, "%c", localtime((time_t *) &timestamp)))
-       return(0);
-    else
-       return(ENOMEM);
-#else  /* HAVE_STRFTIME */
-    if (strlen(ctime((time_t *) &timestamp)) <= buflen) {
-       strcpy(buffer, ctime((time_t *) &timestamp));
-       /* ctime returns <datestring>\n\0 */
-       buffer[strlen(buffer)-1] = '\0';
-       return(0);
-    }
-#endif /* HAVE_STRFTIME */
-    return(ENOMEM);
-}
-
-krb5_error_code
-krb5_timestamp_to_sfstring(timestamp, buffer, buflen, pad)
-    krb5_timestamp     timestamp;
-    char               * buffer;
-    size_t             buflen;
-    char               * pad;
-{
-    struct tm  *tmp;
-    size_t i;
-    size_t     ndone;
-
-    tmp = localtime((time_t *) &timestamp);
-    ndone = 0;
-#if    HAVE_STRFTIME
-    for (i=0; i<sftime_format_table_nents; i++) {
-       if ((ndone = strftime(buffer, buflen, sftime_format_table[i], tmp)))
-           break;
-    }
-#endif /* HAVE_STRFTIME */
-    if (!ndone) {
-       if (buflen >= sftime_default_len) {
-           sprintf(buffer, sftime_default_fmt,
-                   tmp->tm_mday, tmp->tm_mon+1, tmp->tm_year,
-                   tmp->tm_hour, tmp->tm_min, tmp->tm_sec);
-           ndone = strlen(buffer);
-       }
-    }
-    if (ndone && pad) {
-       for (i=ndone; i<buflen-1; i++)
-           buffer[i] = *pad;
-       buffer[buflen-1] = '\0';
-    }
-    return((ndone) ? 0 : ENOMEM);
-}
-
-krb5_error_code
-krb5_deltat_to_string(deltat, buffer, buflen)
-    krb5_deltat        deltat;
-    char       * buffer;
-    size_t     buflen;
-{
-    int                        days, hours, minutes, seconds;
-    krb5_deltat                dt;
-    krb5_error_code    retval;
-
-    days = (int) (deltat / (24*3600l));
-    dt = deltat % (24*3600l);
-    hours = (int) (dt / 3600);
-    dt %= 3600;
-    minutes = (int) (dt / 60);
-    seconds = (int) (dt % 60);
-
-    retval = 0;
-    if (days) {
-       if (hours || minutes || seconds) {
-           if (buflen < (strlen(dt_output_dhms)+strlen(dt_day_plural)))
-               retval = ENOMEM;
-           else
-               sprintf(buffer, dt_output_dhms, days,
-                       (days > 1) ? dt_day_plural : dt_day_singular,
-                       hours, minutes, seconds);
-       }
-       else {
-           if (buflen < (strlen(dt_output_donly)+strlen(dt_day_plural)))
-               retval = ENOMEM;
-           else
-               sprintf(buffer, dt_output_donly, days,
-                       (days > 1) ? dt_day_plural : dt_day_singular);
-       }
-    }
-    else {
-       if (buflen < strlen(dt_output_hms))
-           retval = ENOMEM;
-       else
-           sprintf(buffer, dt_output_hms, hours, minutes, seconds);
-    }
-    return(retval);
-}
index 27e7fac9690b1b015eaa1cc47fae6ced3f529810..2d1c7978eb238c6ec0d26a7038501b8552727dc7 100644 (file)
@@ -75,6 +75,7 @@ OBJS= addr_comp.$(OBJEXT)     \
        ser_princ.$(OBJEXT)     \
        serialize.$(OBJEXT)     \
        srv_rcache.$(OBJEXT)    \
+       str_conv.$(OBJEXT)      \
        tgtname.$(OBJEXT)       \
        unparse.$(OBJEXT)       \
        walk_rtree.$(OBJEXT)
@@ -147,6 +148,7 @@ SRCS=       $(srcdir)/addr_comp.c   \
        $(srcdir)/ser_princ.c   \
        $(srcdir)/serialize.c   \
        $(srcdir)/srv_rcache.c  \
+       $(srcdir)/str_conv.c    \
        $(srcdir)/tgtname.c     \
        $(srcdir)/unparse.c     \
        $(srcdir)/walk_rtree.c
diff --git a/src/lib/krb5/krb/str_conv.c b/src/lib/krb5/krb/str_conv.c
new file mode 100644 (file)
index 0000000..4190b03
--- /dev/null
@@ -0,0 +1,668 @@
+/*
+ * lib/kadm/str_conv.c
+ *
+ * Copyright 1995 by the Massachusetts Institute of Technology.
+ * All Rights Reserved.
+ *
+ * Export of this software from the United States of America may
+ *   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
+ * notice appear in all copies and that both that copyright notice and
+ * this permission notice appear in supporting documentation, and that
+ * the name of M.I.T. not be used in advertising or publicity pertaining
+ * to distribution of the software without specific, written prior
+ * permission.  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.
+ *
+ */
+
+/*
+ * str_conv.c - Convert between strings and Kerberos internal data.
+ */
+
+/*
+ * Table of contents:
+ *
+ * String decoding:
+ * ----------------
+ * krb5_string_to_enctype()    - Convert string to krb5_enctype.
+ * krb5_string_to_salttype()   - Convert string to salttype (krb5_int32)
+ * krb5_string_to_cksumtype()  - Convert string to krb5_cksumtype;
+ * krb5_string_to_timestamp()  - Convert string to krb5_timestamp.
+ * krb5_string_to_deltat()     - Convert string to krb5_deltat.
+ *
+ * String encoding:
+ * ----------------
+ * krb5_enctype_to_string()    - Convert krb5_enctype to string.
+ * krb5_salttype_to_string()   - Convert salttype (krb5_int32) to string.
+ * krb5_cksumtype_to_string()  - Convert krb5_cksumtype to string.
+ * krb5_timestamp_to_string()  - Convert krb5_timestamp to string.
+ * krb5_timestamp_to_sfstring()        - Convert krb5_timestamp to short filled string
+ * krb5_deltat_to_string()     - Convert krb5_deltat to string.
+ */
+
+#include "k5-int.h"
+
+/*
+ * Local data structures.
+ */
+struct enctype_lookup_entry {
+    krb5_enctype       ktt_enctype;            /* Keytype              */
+    const char *       ktt_specifier;          /* How to recognize it  */
+    const char *       ktt_output;             /* How to spit it out   */
+};
+
+struct salttype_lookup_entry {
+    krb5_int32         stt_enctype;            /* Salt type            */
+    const char *       stt_specifier;          /* How to recognize it  */
+    const char *       stt_output;             /* How to spit it out   */
+};
+
+struct cksumtype_lookup_entry {
+    krb5_cksumtype     cst_cksumtype;          /* Checksum type        */
+    const char *       cst_specifier;          /* How to recognize it  */
+    const char *       cst_output;             /* How to spit it out   */
+};
+
+struct deltat_match_entry {
+    const char *       dt_scan_format;         /* sscanf format        */
+    int                        dt_nmatch;              /* Number to match      */
+    int                        dt_dindex;              /* Day index            */
+    int                        dt_hindex;              /* Hour index           */
+    int                        dt_mindex;              /* Minute index         */
+    int                        dt_sindex;              /* Second index         */
+};
+
+/*
+ * Local strings
+ */
+
+/* Keytype strings */
+static const char enctype_des_in[]             = "des";
+static const char enctype_null_in[]            = "null";
+static const char enctype_descbccrc_in[]       = "des-cbc-crc";
+static const char enctype_descbcmd4_in[]       = "des-cbc-md4";
+static const char enctype_descbcmd5_in[]       = "des-cbc-md5";
+static const char enctype_des3cbcmd5_in[]      = "des3-cbc-md5";
+static const char enctype_descbcraw_in[]       = "des-cbc-raw";
+static const char enctype_null_out[]           = "Null";
+static const char enctype_descbccrc_out[]      = "DES cbc mode with CRC-32";
+static const char enctype_descbcmd4_out[]      = "DES cbc mode with RSA-MD4";
+static const char enctype_descbcmd5_out[]      = "DES cbc mode with RSA-MD5";
+static const char enctype_des3cbcmd5_out[]     = "Triple DES cbc mode with RSA-MD5";
+static const char enctype_descbcraw_out[]      = "DES cbc mode raw";
+
+/* Salttype strings */
+static const char stype_v5_in[]                = "normal";
+static const char stype_v4_in[]                = "v4";
+static const char stype_norealm_in[]   = "norealm";
+static const char stype_olrealm_in[]   = "onlyrealm";
+static const char stype_special_in[]   = "special";
+static const char stype_v5_out[]       = "Version 5";
+static const char stype_v4_out[]       = "Version 4";
+static const char stype_norealm_out[]  = "Version 5 - No Realm";
+static const char stype_olrealm_out[]  = "Version 5 - Realm Only";
+static const char stype_special_out[]  = "Special";
+
+/* Checksum type strings */
+static const char cstype_crc32_in[]    = "crc32";
+static const char cstype_md4_in[]      = "md4";
+static const char cstype_md4des_in[]   = "md4-des";
+static const char cstype_descbc_in[]   = "des-cbc";
+static const char cstype_md5_in[]      = "md5";
+static const char cstype_md5des_in[]   = "md5-des";
+static const char cstype_crc32_out[]   = "CRC-32";
+static const char cstype_md4_out[]     = "RSA-MD4";
+static const char cstype_md4des_out[]  = "RSA-MD4 with DES cbc mode";
+static const char cstype_descbc_out[]  = "DES cbc mode";
+static const char cstype_md5_out[]     = "RSA-MD5";
+static const char cstype_md5des_out[]  = "RSA-MD5 with DES cbc mode";
+
+/* Absolute time strings */
+static const char atime_full_digits[]  = "%y%m%d%H%M%S";
+static const char atime_full_digits_d[]        = "%y.%m.%d.%H.%M.%S";
+static const char atime_nsec_digits[]  = "%y%m%d%H%M";
+static const char atime_rel_hms[]      = "%H%M%S";
+static const char atime_rel_hm[]       = "%H%M";
+static const char atime_rel_col_hms[]  = "%T";
+static const char atime_rel_col_hm[]   = "%R";
+static const char atime_ldep_sfmt[]    = "%x:%X";
+static const char atime_full_text[]    = "%d-%b-%Y:%T";
+static const char atime_full_text_nos[]        = "%d-%b-%Y:%R";
+#if    !HAVE_STRPTIME
+static const char ascan_full_digits[]  = "%02d%02d%02d%02d%02d%02d";
+static const char ascan_full_digits_d[]        = "%02d.%02d.%02d.%02d.%02d.%02d";
+static const char ascan_nsec_digits[]  = "%02d%02d%02d%02d%02d";
+static const char ascan_rel_hms[]      = "%02d%02d%02d";
+static const char ascan_rel_hm[]       = "%02d%02d";
+static const char ascan_rel_col_hms[]  = "%02d:%02d:%02d";
+static const char ascan_rel_col_hm[]   = "%02d:%02d";
+#endif /* !HAVE_STRPTIME */
+#ifdef HAVE_STRFTIME
+static const char sftime_ldep_time[]   = "%c";
+static const char sftime_med_fmt[]     = "%d %b %y %T";
+static const char sftime_short_fmt[]   = "%x %X";
+static const char sftime_last_fmt[]    = "%d/%m/%y %R";
+#endif /* HAVE_STRFTIME */
+static const char sftime_default_fmt[] = "%02d/%02d/%02d %02d:%02d";
+static const size_t sftime_default_len = 2+1+2+1+2+1+2+1+2+1;
+
+/* Delta time strings */
+static const char dtscan_dhms_notext[] = "%d-%02d:%02d:%02d";
+static const char dtscan_dhms_stext[]  = "%dd%dh%dm%ds";
+static const char dtscan_hms_notext[]  = "%d:%02d:%02d";
+static const char dtscan_hms_stext[]   = "%dh%dm%ds";
+static const char dtscan_hm_notext[]   = "%d:%02d";
+static const char dtscan_hm_stext[]    = "%dh%dm";
+static const char dtscan_days[]                = "%d%[d]";
+static const char dtscan_hours[]       = "%d%[h]";
+static const char dtscan_minutes[]     = "%d%[m]";
+static const char dtscan_seconds[]     = "%d%[s]";
+static const char dt_day_singular[]    = "day";
+static const char dt_day_plural[]      = "days";
+static const char dt_output_donly[]    = "%d %s";
+static const char dt_output_dhms[]     = "%d %s %02d:%02d:%02d";
+static const char dt_output_hms[]      = "%d:%02d:%02d";
+
+/*
+ * Lookup tables.
+ */
+
+static const struct enctype_lookup_entry enctype_table[] = {
+/* krb5_enctype                input specifier         output string           */
+/*-------------                ----------------------- ------------------------*/
+{ ENCTYPE_NULL,                enctype_null_in,        enctype_null_out        },
+{ ENCTYPE_DES_CBC_MD5, enctype_des_in,         enctype_descbcmd5_out   },
+{ ENCTYPE_DES_CBC_CRC, enctype_descbccrc_in,   enctype_descbccrc_out   },
+{ ENCTYPE_DES_CBC_MD4, enctype_descbcmd4_in,   enctype_descbcmd4_out   },
+{ ENCTYPE_DES_CBC_MD5, enctype_descbcmd5_in,   enctype_descbcmd5_out   },
+{ ENCTYPE_DES3_CBC_MD5,        enctype_des3cbcmd5_in,  enctype_des3cbcmd5_out  },
+{ ENCTYPE_DES_CBC_RAW, enctype_descbcraw_in,   enctype_descbcraw_out   }
+};
+static const int enctype_table_nents = sizeof(enctype_table)/
+                                      sizeof(enctype_table[0]);
+
+static const struct salttype_lookup_entry salttype_table[] = {
+/* salt type                   input specifier         output string     */
+/*-----------------------------        ----------------------- ------------------*/
+{ KRB5_KDB_SALTTYPE_NORMAL,    stype_v5_in,            stype_v5_out      },
+{ KRB5_KDB_SALTTYPE_V4,                stype_v4_in,            stype_v4_out      },
+{ KRB5_KDB_SALTTYPE_NOREALM,   stype_norealm_in,       stype_norealm_out },
+{ KRB5_KDB_SALTTYPE_ONLYREALM, stype_olrealm_in,       stype_olrealm_out },
+{ KRB5_KDB_SALTTYPE_SPECIAL,   stype_special_in,       stype_special_out }
+};
+static const int salttype_table_nents = sizeof(salttype_table)/
+                                       sizeof(salttype_table[0]);
+
+static const struct cksumtype_lookup_entry cksumtype_table[] = {
+/* krb5_cksumtype         input specifier      output string           */
+/*----------------------- ---------------------        ------------------------*/
+{ CKSUMTYPE_CRC32,        cstype_crc32_in,     cstype_crc32_out        },
+{ CKSUMTYPE_RSA_MD4,      cstype_md4_in,       cstype_md4_out          },
+{ CKSUMTYPE_RSA_MD4_DES,  cstype_md4des_in,    cstype_md4des_out       },
+{ CKSUMTYPE_DESCBC,       cstype_descbc_in,    cstype_descbc_out       },
+{ CKSUMTYPE_RSA_MD5,      cstype_md5_in,       cstype_md5_out          },
+{ CKSUMTYPE_RSA_MD5_DES,  cstype_md5des_in,    cstype_md5des_out       }
+};
+static const int cksumtype_table_nents = sizeof(cksumtype_table)/
+                                        sizeof(cksumtype_table[0]);
+
+static const char * const atime_format_table[] = {
+atime_full_digits,     /* yymmddhhmmss                 */
+atime_full_digits_d,   /* yy.mm.dd.hh.mm.ss            */
+atime_nsec_digits,     /* yymmddhhmm                   */
+atime_rel_hms,         /* hhmmss                       */
+atime_rel_hm,          /* hhmm                         */
+atime_rel_col_hms,     /* hh:mm:ss                     */
+atime_rel_col_hm,      /* hh:mm                        */
+/* The following not really supported unless native strptime present */
+atime_ldep_sfmt,       /*locale-dependent short format */
+atime_full_text,       /* dd-month-yyyy:hh:mm:ss       */
+atime_full_text_nos    /* dd-month-yyyy:hh:mm          */
+};
+static const int atime_format_table_nents = sizeof(atime_format_table)/
+                                           sizeof(atime_format_table[0]);
+
+#ifdef HAVE_STRFTIME
+static const char * const sftime_format_table[] = {
+sftime_ldep_time,      /* Default locale-dependent date and time       */
+sftime_med_fmt,                /* dd mon yy hh:mm:ss                           */
+sftime_short_fmt,      /* locale-dependent short format                */
+sftime_last_fmt                /* dd/mm/yy hh:mm                               */
+};
+static const int sftime_format_table_nents = sizeof(sftime_format_table)/
+                                           sizeof(sftime_format_table[0]);
+#endif /* HAVE_STRFTIME */
+
+static const struct deltat_match_entry deltat_table[] = {
+/* scan format         nmatch  daypos  hourpos minpos  secpos  */
+/*---------------------        ------- ------- ------- ------- --------*/
+{ dtscan_dhms_notext,  4,      0,      1,      2,      3       },
+{ dtscan_dhms_stext,   4,      0,      1,      2,      3       },
+{ dtscan_hms_notext,   3,      -1,     0,      1,      2       },
+{ dtscan_hms_stext,    3,      -1,     0,      1,      2       },
+{ dtscan_hm_notext,    2,      -1,     -1,     0,      1       },
+{ dtscan_hm_stext,     2,      -1,     -1,     0,      1       },
+{ dtscan_days,         2,      0,      -1,     -1,     -1      },
+{ dtscan_hours,                2,      -1,     0,      -1,     -1      },
+{ dtscan_minutes,      2,      -1,     -1,     0,      -1      },
+{ dtscan_seconds,      2,      -1,     -1,     -1,     0       }
+};
+static const int deltat_table_nents = sizeof(deltat_table)/
+                                     sizeof(deltat_table[0]);
+\f
+#if    !HAVE_STRPTIME
+/*
+ * Rudimentary version of strptime for systems which don't have it.
+ */
+static char *
+strptime(buf, format, tm)
+    char *buf;
+    const char *format;
+    struct tm *tm;
+{
+    int year, month, day, hour, minute, second;
+    char *bp;
+    time_t now;
+    
+    /*
+     * We only understand the following fixed formats:
+     *    %y%m%d%H%M%S
+     *    %y.%m.%d.%H.%M.%S
+     *    %y%m%d%H%M
+     *    %H%M%S
+     *    %H%M
+     *    %T
+     *    %R
+     */
+    bp = (char *) NULL;
+    if (!strcmp(format, atime_full_digits) &&
+       (sscanf(buf, ascan_full_digits,
+               &year, &month, &day, &hour, &minute, &second) == 6)) {
+       tm->tm_year = year;
+       tm->tm_mon = month - 1;
+       tm->tm_mday = day;
+       tm->tm_hour = hour;
+       tm->tm_min = minute;
+       tm->tm_sec = second;
+       bp = &buf[strlen(atime_full_digits)];
+    }
+    else if (!strcmp(format,atime_full_digits_d) &&
+            (sscanf(buf, ascan_full_digits_d,
+                    &year, &month, &day, &hour, &minute, &second) == 6)) {
+       tm->tm_year = year;
+       tm->tm_mon = month - 1;
+       tm->tm_mday = day;
+       tm->tm_hour = hour;
+       tm->tm_min = minute;
+       tm->tm_sec = second;
+       bp = &buf[strlen(atime_full_digits_d)];
+    }
+    else if (!strcmp(format, atime_nsec_digits) &&
+            (sscanf(buf, ascan_nsec_digits,
+               &year, &month, &day, &hour, &minute) == 5)) {
+       tm->tm_year = year;
+       tm->tm_mon = month - 1;
+       tm->tm_mday = day;
+       tm->tm_hour = hour;
+       tm->tm_min = minute;
+       tm->tm_sec = 0;
+       bp = &buf[strlen(atime_nsec_digits)];
+    }
+    else if (!strcmp(format, atime_rel_hms) &&
+            (sscanf(buf, ascan_rel_hms, &hour, &minute, &second) == 3)) {
+       now = time((time_t *) NULL);
+       memcpy(tm, localtime(&now), sizeof(struct tm));
+       tm->tm_hour = hour;
+       tm->tm_min = minute;
+       tm->tm_sec = second;
+       bp = &buf[strlen(atime_rel_hms)];
+    }
+    else if (!strcmp(format, atime_rel_hm) &&
+            (sscanf(buf, ascan_rel_hm, &hour, &minute) == 2)) {
+       now = time((time_t *) NULL);
+       memcpy(tm, localtime(&now), sizeof(struct tm));
+       tm->tm_hour = hour;
+       tm->tm_min = minute;
+       bp = &buf[strlen(atime_rel_hm)];
+    }
+    else if (!strcmp(format, atime_rel_col_hms) &&
+            (sscanf(buf, ascan_rel_col_hms, &hour, &minute, &second) == 3)) {
+       now = time((time_t *) NULL);
+       memcpy(tm, localtime(&now), sizeof(struct tm));
+       tm->tm_hour = hour;
+       tm->tm_min = minute;
+       tm->tm_sec = second;
+       bp = &buf[strlen(atime_rel_col_hms)];
+    }
+    else if (!strcmp(format, atime_rel_col_hm) &&
+            (sscanf(buf, ascan_rel_col_hm, &hour, &minute) == 2)) {
+       now = time((time_t *) NULL);
+       memcpy(tm, localtime(&now), sizeof(struct tm));
+       tm->tm_hour = hour;
+       tm->tm_min = minute;
+       bp = &buf[strlen(atime_rel_col_hm)];
+    }
+    return(bp);
+}
+#endif /* HAVE_STRPTIME */
+\f
+/*
+ * String to internal datatype routines.
+ *
+ * These routines return 0 for success, EINVAL for invalid entry.
+ */
+krb5_error_code
+krb5_string_to_enctype(string, enctypep)
+    char               * string;
+    krb5_enctype       * enctypep;
+{
+    int i;
+    int found;
+
+    found = 0;
+    for (i=0; i<enctype_table_nents; i++) {
+       if (!strcasecmp(string, enctype_table[i].ktt_specifier)) {
+           found = 1;
+           *enctypep = enctype_table[i].ktt_enctype;
+           break;
+       }
+    }
+    return((found) ? 0 : EINVAL);
+}
+
+krb5_error_code
+krb5_string_to_salttype(string, salttypep)
+    char       * string;
+    krb5_int32 * salttypep;
+{
+    int i;
+    int found;
+
+    found = 0;
+    for (i=0; i<salttype_table_nents; i++) {
+       if (!strcasecmp(string, salttype_table[i].stt_specifier)) {
+           found = 1;
+           *salttypep = salttype_table[i].stt_enctype;
+           break;
+       }
+    }
+    return((found) ? 0 : EINVAL);
+}
+
+krb5_error_code
+krb5_string_to_cksumtype(string, cksumtypep)
+    char               * string;
+    krb5_cksumtype     * cksumtypep;
+{
+    int i;
+    int found;
+
+    found = 0;
+    for (i=0; i<cksumtype_table_nents; i++) {
+       if (!strcasecmp(string, cksumtype_table[i].cst_specifier)) {
+           found = 1;
+           *cksumtypep = cksumtype_table[i].cst_cksumtype;
+           break;
+       }
+    }
+    return((found) ? 0 : EINVAL);
+}
+
+krb5_error_code
+krb5_string_to_timestamp(string, timestampp)
+    char               * string;
+    krb5_timestamp     * timestampp;
+{
+    int i;
+    int found;
+    struct tm timebuf;
+
+    found = 0;
+    memset(&timebuf, 0, sizeof(timebuf));
+    for (i=0; i<atime_format_table_nents; i++) {
+       if (strptime(string, atime_format_table[i], &timebuf)) {
+           found = 1;
+           break;
+       }
+    }
+    if (found)
+       *timestampp = (krb5_timestamp) mktime(&timebuf);
+    return((found) ? 0 : EINVAL);
+}
+
+krb5_error_code
+krb5_string_to_deltat(string, deltatp)
+    char       * string;
+    krb5_deltat        * deltatp;
+{
+    int i;
+    int found;
+    int svalues[4];
+    int days, hours, minutes, seconds;
+    krb5_deltat        dt;
+
+    found = 0;
+    days = hours = minutes = seconds = 0;
+    for (i=0; i<deltat_table_nents; i++) {
+       if (sscanf(string, deltat_table[i].dt_scan_format,
+                  &svalues[0], &svalues[1], &svalues[2], &svalues[3]) ==
+           deltat_table[i].dt_nmatch) {
+           if (deltat_table[i].dt_dindex >= 0)
+               days = svalues[deltat_table[i].dt_dindex];
+           if (deltat_table[i].dt_hindex >= 0)
+               hours = svalues[deltat_table[i].dt_hindex];
+           if (deltat_table[i].dt_mindex >= 0)
+               minutes = svalues[deltat_table[i].dt_mindex];
+           if (deltat_table[i].dt_sindex >= 0)
+               seconds = svalues[deltat_table[i].dt_sindex];
+           found = 1;
+           break;
+       }
+    }
+    if (found) {
+       dt = days;
+       dt *= 24;
+       dt += hours;
+       dt *= 60;
+       dt += minutes;
+       dt *= 60;
+       dt += seconds;
+       *deltatp = dt;
+    }
+    return((found) ? 0 : EINVAL);
+}
+
+/*
+ * Internal datatype to string routines.
+ *
+ * These routines return 0 for success, EINVAL for invalid parameter, ENOMEM
+ * if the supplied buffer/length will not contain the output.
+ */
+krb5_error_code
+krb5_enctype_to_string(enctype, buffer, buflen)
+    krb5_enctype       enctype;
+    char               * buffer;
+    size_t             buflen;
+{
+    int i;
+    const char *out;
+
+    out = (char *) NULL;
+    for (i=0; i<enctype_table_nents; i++) {
+       if (enctype ==  enctype_table[i].ktt_enctype) {
+           out = enctype_table[i].ktt_output;
+           break;
+       }
+    }
+    if (out) {
+       if (buflen > strlen(out))
+           strcpy(buffer, out);
+       else
+           out = (char *) NULL;
+       return((out) ? 0 : ENOMEM);
+    }
+    else
+       return(EINVAL);
+}
+
+krb5_error_code
+krb5_salttype_to_string(salttype, buffer, buflen)
+    krb5_int32 salttype;
+    char       * buffer;
+    size_t     buflen;
+{
+    int i;
+    const char *out;
+
+    out = (char *) NULL;
+    for (i=0; i<salttype_table_nents; i++) {
+       if (salttype ==  salttype_table[i].stt_enctype) {
+           out = salttype_table[i].stt_output;
+           break;
+       }
+    }
+    if (out) {
+       if (buflen > strlen(out))
+           strcpy(buffer, out);
+       else
+           out = (char *) NULL;
+       return((out) ? 0 : ENOMEM);
+    }
+    else
+       return(EINVAL);
+}
+
+krb5_error_code
+krb5_cksumtype_to_string(cksumtype, buffer, buflen)
+    krb5_cksumtype     cksumtype;
+    char               * buffer;
+    size_t             buflen;
+{
+    int i;
+    const char *out;
+
+    out = (char *) NULL;
+    for (i=0; i<cksumtype_table_nents; i++) {
+       if (cksumtype ==  cksumtype_table[i].cst_cksumtype) {
+           out = cksumtype_table[i].cst_output;
+           break;
+       }
+    }
+    if (out) {
+       if (buflen > strlen(out))
+           strcpy(buffer, out);
+       else
+           out = (char *) NULL;
+       return((out) ? 0 : ENOMEM);
+    }
+    else
+       return(EINVAL);
+}
+
+krb5_error_code
+krb5_timestamp_to_string(timestamp, buffer, buflen)
+    krb5_timestamp     timestamp;
+    char               * buffer;
+    size_t             buflen;
+{
+#if    HAVE_STRFTIME
+    if (strftime(buffer, buflen, "%c", localtime((time_t *) &timestamp)))
+       return(0);
+    else
+       return(ENOMEM);
+#else  /* HAVE_STRFTIME */
+    if (strlen(ctime((time_t *) &timestamp)) <= buflen) {
+       strcpy(buffer, ctime((time_t *) &timestamp));
+       /* ctime returns <datestring>\n\0 */
+       buffer[strlen(buffer)-1] = '\0';
+       return(0);
+    }
+#endif /* HAVE_STRFTIME */
+    return(ENOMEM);
+}
+
+krb5_error_code
+krb5_timestamp_to_sfstring(timestamp, buffer, buflen, pad)
+    krb5_timestamp     timestamp;
+    char               * buffer;
+    size_t             buflen;
+    char               * pad;
+{
+    struct tm  *tmp;
+    size_t i;
+    size_t     ndone;
+
+    tmp = localtime((time_t *) &timestamp);
+    ndone = 0;
+#if    HAVE_STRFTIME
+    for (i=0; i<sftime_format_table_nents; i++) {
+       if ((ndone = strftime(buffer, buflen, sftime_format_table[i], tmp)))
+           break;
+    }
+#endif /* HAVE_STRFTIME */
+    if (!ndone) {
+       if (buflen >= sftime_default_len) {
+           sprintf(buffer, sftime_default_fmt,
+                   tmp->tm_mday, tmp->tm_mon+1, tmp->tm_year,
+                   tmp->tm_hour, tmp->tm_min, tmp->tm_sec);
+           ndone = strlen(buffer);
+       }
+    }
+    if (ndone && pad) {
+       for (i=ndone; i<buflen-1; i++)
+           buffer[i] = *pad;
+       buffer[buflen-1] = '\0';
+    }
+    return((ndone) ? 0 : ENOMEM);
+}
+
+krb5_error_code
+krb5_deltat_to_string(deltat, buffer, buflen)
+    krb5_deltat        deltat;
+    char       * buffer;
+    size_t     buflen;
+{
+    int                        days, hours, minutes, seconds;
+    krb5_deltat                dt;
+    krb5_error_code    retval;
+
+    days = (int) (deltat / (24*3600l));
+    dt = deltat % (24*3600l);
+    hours = (int) (dt / 3600);
+    dt %= 3600;
+    minutes = (int) (dt / 60);
+    seconds = (int) (dt % 60);
+
+    retval = 0;
+    if (days) {
+       if (hours || minutes || seconds) {
+           if (buflen < (strlen(dt_output_dhms)+strlen(dt_day_plural)))
+               retval = ENOMEM;
+           else
+               sprintf(buffer, dt_output_dhms, days,
+                       (days > 1) ? dt_day_plural : dt_day_singular,
+                       hours, minutes, seconds);
+       }
+       else {
+           if (buflen < (strlen(dt_output_donly)+strlen(dt_day_plural)))
+               retval = ENOMEM;
+           else
+               sprintf(buffer, dt_output_donly, days,
+                       (days > 1) ? dt_day_plural : dt_day_singular);
+       }
+    }
+    else {
+       if (buflen < strlen(dt_output_hms))
+           retval = ENOMEM;
+       else
+           sprintf(buffer, dt_output_hms, hours, minutes, seconds);
+    }
+    return(retval);
+}