return retval;
}
-#ifdef KRB5_KRB4_COMPAT
-/*
- * getstr() takes a file pointer, a string and a count. It reads from
- * the file until either it has read "count" characters, or until it
- * reads a null byte. When finished, what has been read exists in the
- * given string "s". If "count" characters were actually read, the
- * last is changed to a null, so the returned string is always null-
- * terminated. getstr() returns the number of characters read,
- * including the null terminator.
- */
-
-static int getstr(fp, s, n)
- FILE *fp;
- register char *s;
- int n;
-{
- register int count = n;
- while (fread(s, 1, 1, fp) > 0 && --count)
- if (*s++ == '\0')
- return (n - count);
- *s = '\0';
- return (n - count);
-}
-
/*
* Read in a named krb4 srvtab and append to list. Allocate new list
* if needed.
char *name;
krb5_kt_list *list;
{
- krb5_kt_list lp = NULL, tail = NULL, back = NULL;
- krb5_keytab_entry *entry;
- krb5_error_code retval = 0;
- char sname[SNAME_SZ]; /* name of service */
- char sinst[INST_SZ]; /* instance of service */
- char srealm[REALM_SZ]; /* realm of service */
- unsigned char kvno; /* key version number */
- des_cblock key;
- FILE *fp;
+ char *ktname;
+ krb5_error_code result;
- if (*list) {
- /* point lp at the tail of the list */
- for (lp = *list; lp->next; lp = lp->next);
- back = lp;
- }
- fp = fopen(name, "r");
- if (!fp)
- return EIO;
- for (;;) {
- entry = (krb5_keytab_entry *)malloc(sizeof (krb5_keytab_entry));
- if (!entry) {
- retval = ENOMEM;
- break;
- }
- memset((char *)entry, 0, sizeof (*entry));
- memset(sname, 0, sizeof (sname));
- memset(sinst, 0, sizeof (sinst));
- memset(srealm, 0, sizeof (srealm));
- if (!(getstr(fp, sname, SNAME_SZ) > 0 &&
- getstr(fp, sinst, INST_SZ) > 0 &&
- getstr(fp, srealm, REALM_SZ) > 0 &&
- fread(&kvno, 1, 1, fp) > 0 &&
- fread((char *)key, sizeof (key), 1, fp) > 0))
- break;
- entry->magic = KV5M_KEYTAB_ENTRY;
- entry->timestamp = 0; /* XXX */
- entry->vno = kvno;
- retval = krb5_425_conv_principal(context,
- sname, sinst, srealm,
- &entry->principal);
- if (retval)
- break;
- entry->key.magic = KV5M_KEYBLOCK;
- entry->key.enctype = ENCTYPE_DES_CBC_CRC;
- entry->key.length = sizeof (key);
- entry->key.contents = (krb5_octet *)malloc(sizeof (key));
- if (!entry->key.contents) {
- retval = ENOMEM;
- break;
- }
- memcpy((char *)entry->key.contents, (char *)key, sizeof (key));
- if (!lp) { /* if list is empty, start one */
- lp = (krb5_kt_list)malloc(sizeof (*lp));
- if (!lp) {
- retval = ENOMEM;
- break;
- }
- } else {
- lp->next = (krb5_kt_list)malloc(sizeof (*lp));
- if (!lp->next) {
- retval = ENOMEM;
- break;
- }
- lp = lp->next;
- }
- lp->next = NULL;
- lp->entry = entry;
- if (!tail)
- tail = lp;
- }
- if (entry) {
- if (entry->magic == KV5M_KEYTAB_ENTRY)
- krb5_kt_free_entry(context, entry);
- free((char *)entry);
- }
- if (retval) {
- ktutil_free_kt_list(context, tail);
- tail = NULL;
- if (back)
- back->next = NULL;
- }
- if (!*list)
- *list = tail;
- fclose(fp);
- return retval;
-}
-
-/*
- * Writes a kt_list out to a krb4 srvtab file. Note that it first
- * prunes the kt_list so that it won't contain any keys that are not
- * the most recent, and ignores keys that are not ENCTYPE_DES.
- */
-krb5_error_code ktutil_write_srvtab(context, list, name)
- krb5_context context;
- krb5_kt_list list;
- char *name;
-{
- krb5_kt_list lp, lp1, prev, pruned = NULL;
- krb5_error_code retval = 0;
- FILE *fp;
- char sname[SNAME_SZ];
- char sinst[INST_SZ];
- char srealm[REALM_SZ];
-
- /* First do heinous stuff to prune the list. */
- for (lp = list; lp; lp = lp->next) {
- if ((lp->entry->key.enctype != ENCTYPE_DES_CBC_CRC) &&
- (lp->entry->key.enctype != ENCTYPE_DES_CBC_MD5) &&
- (lp->entry->key.enctype != ENCTYPE_DES_CBC_MD4) &&
- (lp->entry->key.enctype != ENCTYPE_DES_CBC_RAW))
- continue;
-
- for (lp1 = pruned; lp1; prev = lp1, lp1 = lp1->next) {
- /* Hunt for the current principal in the pruned list */
- if (krb5_principal_compare(context,
- lp->entry->principal,
- lp1->entry->principal))
- break;
- }
- if (!lp1) { /* need to add entry to tail of pruned list */
- if (!pruned) {
- pruned = (krb5_kt_list) malloc(sizeof (*pruned));
- if (!pruned)
- return ENOMEM;
- memset((char *) pruned, 0, sizeof(*pruned));
- lp1 = pruned;
- } else {
- prev->next
- = (krb5_kt_list) malloc(sizeof (*pruned));
- if (!prev->next) {
- retval = ENOMEM;
- goto free_pruned;
- }
- memset((char *) prev->next, 0, sizeof(*pruned));
- lp1 = prev->next;
- }
- lp1->entry = lp->entry;
- } else {
- /* This heuristic should be roughly the same as in the
- keytab-reading code in libkrb5. */
- int offset = 0;
- if (lp1->entry->vno > 240 || lp->entry->vno > 240) {
- offset = 128;
- }
-#define M(X) (((X) + offset) % 256)
- if (M(lp1->entry->vno) < M(lp->entry->vno))
- /* Check if lp->entry is newer kvno; if so, update */
- lp1->entry = lp->entry;
- }
- }
- umask(0077); /*Changing umask for all of ktutil is OK
- * We don't ever write out anything that should use
- * default umask.*/
- fp = fopen(name, "w");
- if (!fp) {
- retval = EIO;
- goto free_pruned;
- }
- for (lp = pruned; lp; lp = lp->next) {
- unsigned char kvno;
- kvno = (unsigned char) lp->entry->vno;
- retval = krb5_524_conv_principal(context,
- lp->entry->principal,
- sname, sinst, srealm);
- if (retval)
- break;
- fwrite(sname, strlen(sname) + 1, 1, fp);
- fwrite(sinst, strlen(sinst) + 1, 1, fp);
- fwrite(srealm, strlen(srealm) + 1, 1, fp);
- fwrite((char *)&kvno, 1, 1, fp);
- fwrite((char *)lp->entry->key.contents,
- sizeof (des_cblock), 1, fp);
- }
- fclose(fp);
- free_pruned:
- /*
- * Loop over and free the pruned list; don't use free_kt_list
- * because that kills the entries.
- */
- for (lp = pruned; lp;) {
- prev = lp;
- lp = lp->next;
- free((char *)prev);
- }
- return retval;
+ if (asprintf(&ktname, "SRVTAB:%s", name) < 0)
+ return ENOMEM;
+ result = ktutil_read_keytab(context, ktname, list);
+ free(ktname);
+ return result;
}
-#endif /* KRB5_KRB4_COMPAT */