SS functions are void
authorJohn Kohl <jtkohl@mit.edu>
Tue, 8 May 1990 16:12:12 +0000 (16:12 +0000)
committerJohn Kohl <jtkohl@mit.edu>
Tue, 8 May 1990 16:12:12 +0000 (16:12 +0000)
add extract_srvtab
add error checking on fetch of master key

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

src/admin/edit/kdb5_edit.c

index 4eede1cbfb2c05df031784a661436f812ff28124..a72908c4a6a4ea1c560335e956010d35929d2ce9 100644 (file)
@@ -26,6 +26,7 @@ static char rcsid_kdb_edit_c[] =
 #include <krb5/libos-proto.h>
 #include <krb5/asn1.h>
 #include <krb5/config.h>
+#include <sys/param.h>                 /* XXX for MAXPATHLEN */
 
 #include <com_err.h>
 #include <ss/ss.h>
@@ -33,6 +34,9 @@ static char rcsid_kdb_edit_c[] =
 
 #include <krb5/ext-proto.h>
 
+#define REALM_SEP      '@'
+#define REALM_SEP_STR  "@"
+
 struct mblock {
     krb5_deltat max_life;
     krb5_deltat max_rlife;
@@ -47,8 +51,8 @@ struct mblock {
     0
 };
 
-krb5_error_code add_key PROTOTYPE((char * const *, const krb5_principal,
-                                  const krb5_keyblock *));
+void add_key PROTOTYPE((char * const *, const krb5_principal,
+                       const krb5_keyblock *));
 int set_dbname_help PROTOTYPE((char *, char *));
 
 static void
@@ -215,7 +219,7 @@ krb5_principal principal;
        return FALSE;
 }
 
-krb5_error_code
+void
 add_new_key(argc, argv)
 int argc;
 char *argv[];
@@ -230,23 +234,23 @@ char *argv[];
     if (argc < 2) {
        com_err(argv[0], 0, "Too few arguments");
        com_err(argv[0], 0, "Usage: add_new_key principal");
-       return 1;
+       return;
     }
     if (retval = krb5_parse_name(argv[1], &newprinc)) {
        com_err(argv[0], retval, "while parsing '%s'", argv[1]);
-       return 1;
+       return;
     }
     if (princ_exists(argv[0], newprinc)) {
        com_err(argv[0], 0, "principal '%s' already exists", argv[1]);
        krb5_free_principal(newprinc);
-       return 1;
+       return;
     }
     if (retval = krb5_read_password(krb5_default_pwd_prompt1,
                                    krb5_default_pwd_prompt2,
                                    password, &pwsize)) {
        com_err(argv[0], retval, "while reading password for '%s'", argv[1]);
        krb5_free_principal(newprinc);
-       return 1;
+       return;
     }
     pwd.data = password;
     pwd.length = pwsize;
@@ -260,16 +264,16 @@ char *argv[];
     if (retval) {
        com_err(argv[0], retval, "while converting password to key for '%s'", argv[1]);
        krb5_free_principal(newprinc);
-       return 1;
+       return;
     }
-    retval = add_key(argv, newprinc, &tempkey);
+    add_key(argv, newprinc, &tempkey);
     bzero((char *)tempkey.contents, tempkey.length);
     free((char *)tempkey.contents);
     krb5_free_principal(newprinc);
-    return retval;
+    return;
 }
 
-krb5_error_code
+void
 add_rnd_key(argc, argv)
 int argc;
 char *argv[];
@@ -280,31 +284,31 @@ char *argv[];
     if (argc < 2) {
        com_err(argv[0], 0, "Too few arguments");
        com_err(argv[0], 0, "Usage: add_rnd_key principal");
-       return 1;
+       return;
     }
     if (retval = krb5_parse_name(argv[1], &newprinc)) {
        com_err(argv[0], retval, "while parsing '%s'", argv[1]);
-       return 1;
+       return;
     }
     if (princ_exists(argv[0], newprinc)) {
        com_err(argv[0], 0, "principal '%s' already exists", argv[1]);
        krb5_free_principal(newprinc);
-       return 1;
+       return;
     }
     if (retval = (*master_encblock.crypto_entry->random_key)(master_random,
                                                             &tempkey)) {
        com_err(argv[0], retval, "while generating random key");
        krb5_free_principal(newprinc);
-       return 1;
+       return;
     }
-    retval = add_key(argv, newprinc, tempkey);
+    add_key(argv, newprinc, tempkey);
     bzero((char *)tempkey->contents, tempkey->length);
     krb5_free_keyblock(tempkey);
     krb5_free_principal(newprinc);
-    return retval;
+    return;
 }
 
-krb5_error_code
+void
 add_key(argv, principal, key)
 char * const *argv;
 const krb5_principal principal;
@@ -320,7 +324,7 @@ const krb5_keyblock *key;
                                  &newentry.key);
     if (retval) {
        com_err(argv[0], retval, "while encrypting key for '%s'", argv[1]);
-       return 1;
+       return;
     }
     newentry.principal = principal;
     newentry.kvno = 1;
@@ -333,7 +337,7 @@ const krb5_keyblock *key;
        com_err(argv[0], retval, "while fetching date");
        bzero((char *)newentry.key.contents, newentry.key.length);
        free((char *)newentry.key.contents);
-       return 1;
+       return;
     }
     newentry.attributes = mblock.flags;
     
@@ -342,16 +346,14 @@ const krb5_keyblock *key;
     free((char *)newentry.key.contents);
     if (retval) {
        com_err(argv[0], retval, "while storing entry for '%s'\n", argv[1]);
-       return 1;
+       return;
     }
-    if (one != 1) {
+    if (one != 1)
        com_err(argv[0], 0, "entry not stored in database (unknown failure)");
-       return 1;
-    }
-    return 0;
+    return;
 }
 
-krb5_error_code
+void
 set_dbname(argc, argv, sci_idx, infop)
 int argc;
 char *argv[];
@@ -366,11 +368,11 @@ krb5_pointer infop;
     if (argc < 3) {
        com_err(argv[0], 0, "Too few arguments");
        com_err(argv[0], 0, "Usage: set_dbname dbpathname realmname");
-       return 1;
+       return;
     }
     if ((retval = krb5_db_fini()) && retval != KRB5_KDB_DBNOTINITED) {
        com_err(argv[0], retval, "while closing previous database");
-       return 1;
+       return;
     }
     (void) (*csentry->finish_key)(&master_encblock);
     (void) (*csentry->finish_random_key)(&master_random);
@@ -378,10 +380,13 @@ krb5_pointer infop;
     cur_realm = malloc(strlen(argv[2])+1);
     if (!cur_realm) {
        com_err(argv[0], 0, "Insufficient memory to proceed");
-       return ss_quit(argc, argv, sci_idx, infop);
+       ss_quit(argc, argv, sci_idx, infop);
+       /*NOTREACHED*/
+       return;
     }
     (void) strcpy(cur_realm, argv[2]);
-    return set_dbname_help(argv[0], argv[1]);
+    (void) set_dbname_help(argv[0], argv[1]);
+    return;
 }
 
 int
@@ -430,7 +435,17 @@ char *dbname;
        com_err(pname, retval, "while retrieving master entry");
        (void) krb5_db_fini();
        return(1);
+    } else if (more) {
+       com_err(pname, KRB5KDC_ERR_PRINCIPAL_NOT_UNIQUE,
+               "while retrieving master entry");
+       (void) krb5_db_fini();
+       return(1);
+    } else if (!nentries) {
+       com_err(pname, KRB5_KDB_NOENTRY, "while retrieving master entry");
+       (void) krb5_db_fini();
+       return(1);
     }
+
     if (retval = (*csentry->process_key)(&master_encblock,
                                         &master_keyblock)) {
        com_err(pname, retval, "while processing master key");
@@ -453,3 +468,115 @@ char *dbname;
     krb5_db_free_principal(&master_entry, nentries);
     return 0;
 }
+
+extern krb5_kt_ops krb5_ktf_writable_ops;
+
+/* this brings in only the writable keytab version, replacing ktdir.c */
+static krb5_kt_ops *krb5_kt_dir_array[] = {
+    &krb5_ktf_writable_ops,
+    0
+};
+
+krb5_kt_ops **krb5_kt_directory = krb5_kt_dir_array;
+
+void
+extract_srvtab(argc, argv)
+int argc;
+char *argv[];
+{
+    char ktname[MAXPATHLEN+sizeof("WRFILE:")+1];
+    krb5_keytab ktid;
+    krb5_error_code retval;
+    krb5_principal princ;
+    krb5_db_entry dbentry;
+    char *pname;
+    register int i;
+    int nentries;
+    krb5_boolean more;
+    krb5_keytab_entry newentry;
+
+    if (argc < 3) {
+       com_err(argv[0], 0, "Too few arguments");
+       com_err(argv[0], 0, "Usage: extract_srvtab instance name [name ...]");
+       return;
+    }
+
+    bzero(ktname, sizeof(ktname));
+    strcpy(ktname, "WRFILE:");
+    if (strlen(argv[1])+sizeof("WRFILE:")+sizeof("-new-srvtab") >= sizeof(ktname)) {
+       com_err(argv[0], 0,
+               "Instance name '%s' is too long to form a filename", argv[1]);
+       com_err(argv[0], 0, "using 'foobar' instead.");
+       strcat(ktname, "foobar");
+    } else
+       strcat(ktname, argv[1]);
+
+    strcat(ktname, "-new-srvtab");
+    if (retval = krb5_kt_resolve(ktname, &ktid)) {
+       com_err(argv[0], retval, "while resolving keytab name '%s'", ktname);
+       return;
+    }
+
+    for (i = 2; i < argc; i++) {
+       /* iterate over the names */
+       pname = malloc(strlen(argv[1])+strlen(argv[i])+strlen(cur_realm)+3);
+       if (!pname) {
+           com_err(argv[0], ENOMEM,
+                   "while preparing to extract key for %s/%s",
+                   argv[i], argv[1]);
+           continue;
+       }
+       strcpy(pname, argv[i]);
+       strcat(pname, "/");
+       strcat(pname, argv[1]);
+       if (!strchr(argv[1], REALM_SEP)) {
+           strcat(pname, REALM_SEP_STR);
+           strcat(pname, cur_realm);
+       }
+
+       if (retval = krb5_parse_name(pname, &princ)) {
+           com_err(argv[0], retval, "while parsing %s", pname);
+           free(pname);
+           continue;
+       }
+       nentries = 1;
+       if (retval = krb5_db_get_principal(princ, &dbentry, &nentries,
+                                          &more)) {
+           com_err(argv[0], retval, "while retrieving %s", pname);
+           goto cleanmost;
+       } else if (more) {
+           com_err(argv[0], KRB5KDC_ERR_PRINCIPAL_NOT_UNIQUE,
+                   "while retrieving %s", pname);
+           if (nentries)
+               krb5_db_free_principal(&dbentry, nentries);
+           goto cleanmost;
+       } else if (!nentries) {
+           com_err(argv[0], KRB5_KDB_NOENTRY, "while retrieving %s", pname);
+           goto cleanmost;
+       }
+       if (retval = krb5_kdb_decrypt_key(&master_encblock,
+                                         &dbentry.key,
+                                         &newentry.key)) {
+           com_err(argv[0], retval, "while decrypting key for '%s'", pname);
+           goto cleanall;
+       }
+       newentry.principal = princ;
+       newentry.vno = dbentry.kvno;
+       if (retval = krb5_kt_add_entry(ktid, &newentry)) {
+           com_err(argv[0], retval, "while adding key to keytab '%s'",
+                   ktname);
+       } else
+           printf("'%s' added to keytab '%s'\n",
+                  pname, ktname);
+       bzero((char *)newentry.key.contents, newentry.key.length);
+       free((char *)newentry.key.contents);
+    cleanall:
+           krb5_db_free_principal(&dbentry, nentries);
+    cleanmost:
+           free(pname);
+           krb5_free_principal(princ);
+    }
+    if (retval = krb5_kt_close(ktid))
+       com_err(argv[0], retval, "while closing keytab");
+    return;
+}