#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>
#include <krb5/ext-proto.h>
+#define REALM_SEP '@'
+#define REALM_SEP_STR "@"
+
struct mblock {
krb5_deltat max_life;
krb5_deltat max_rlife;
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
return FALSE;
}
-krb5_error_code
+void
add_new_key(argc, argv)
int argc;
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;
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[];
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;
&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;
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;
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[];
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);
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
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");
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;
+}