summaryrefslogtreecommitdiffstats
path: root/crypto/kerberosIV/kadmin/ksrvutil_get.c
diff options
context:
space:
mode:
authormarkm <markm@FreeBSD.org>1997-09-04 06:04:33 +0000
committermarkm <markm@FreeBSD.org>1997-09-04 06:04:33 +0000
commita8a89cfaf983bc64f4b42f7c35209a5a36dd0fe8 (patch)
tree0b84977f19022a965f8c6145f067f951173f6290 /crypto/kerberosIV/kadmin/ksrvutil_get.c
downloadFreeBSD-src-a8a89cfaf983bc64f4b42f7c35209a5a36dd0fe8.zip
FreeBSD-src-a8a89cfaf983bc64f4b42f7c35209a5a36dd0fe8.tar.gz
Initial import of KTH eBones. This has been cleaned up to only include
the "core" Kerberos functionality. The rest of the userland will get their own changes later.
Diffstat (limited to 'crypto/kerberosIV/kadmin/ksrvutil_get.c')
-rw-r--r--crypto/kerberosIV/kadmin/ksrvutil_get.c400
1 files changed, 400 insertions, 0 deletions
diff --git a/crypto/kerberosIV/kadmin/ksrvutil_get.c b/crypto/kerberosIV/kadmin/ksrvutil_get.c
new file mode 100644
index 0000000..7b97d35
--- /dev/null
+++ b/crypto/kerberosIV/kadmin/ksrvutil_get.c
@@ -0,0 +1,400 @@
+/*
+ * Copyright (c) 1995, 1996, 1997 Kungliga Tekniska Högskolan
+ * (Royal Institute of Technology, Stockholm, Sweden).
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ *
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * 3. All advertising materials mentioning features or use of this software
+ * must display the following acknowledgement:
+ * This product includes software developed by the Kungliga Tekniska
+ * Högskolan and its contributors.
+ *
+ * 4. Neither the name of the Institute nor the names of its contributors
+ * may be used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE INSTITUTE AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE INSTITUTE OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ */
+
+#include "kadm_locl.h"
+#include "ksrvutil.h"
+
+RCSID("$Id: ksrvutil_get.c,v 1.32 1997/05/05 21:14:57 assar Exp $");
+
+#define BAD_PW 1
+#define GOOD_PW 0
+#define FUDGE_VALUE 15 /* for ticket expiration time */
+#define PE_NO 0
+#define PE_YES 1
+#define PE_UNSURE 2
+
+static char tktstring[128];
+
+static int
+princ_exists(char *name, char *instance, char *realm)
+{
+ int status;
+
+ status = krb_get_pw_in_tkt(name, instance, realm,
+ KRB_TICKET_GRANTING_TICKET,
+ realm, 1, "");
+
+ if ((status == KSUCCESS) || (status == INTK_BADPW))
+ return(PE_YES);
+ else if (status == KDC_PR_UNKNOWN)
+ return(PE_NO);
+ else
+ return(PE_UNSURE);
+}
+
+static int
+get_admin_password(char *myname, char *myinst, char *myrealm)
+{
+ int status;
+ char admin_passwd[MAX_KPW_LEN]; /* Admin's password */
+ int ticket_life = 1; /* minimum ticket lifetime */
+ char buf[1024];
+ CREDENTIALS c;
+
+ if (princ_exists(myname, myinst, myrealm) != PE_NO) {
+ snprintf(buf, sizeof(buf), "Password for %s: ",
+ krb_unparse_name_long (myname, myinst, myrealm));
+ if (des_read_pw_string(admin_passwd, sizeof(admin_passwd)-1,
+ buf, 0)) {
+ fprintf(stderr, "Error reading admin password.\n");
+ goto bad;
+ }
+ status = krb_get_pw_in_tkt(myname, myinst, myrealm, PWSERV_NAME,
+ KADM_SINST, ticket_life, admin_passwd);
+ memset(admin_passwd, 0, sizeof(admin_passwd));
+
+ /* Initialize non shared random sequence from session key. */
+ memset(&c, 0, sizeof(c));
+ krb_get_cred(PWSERV_NAME, KADM_SINST, myrealm, &c);
+ des_init_random_number_generator(&c.session);
+ }
+ else
+ status = KDC_PR_UNKNOWN;
+
+ switch(status) {
+ case GT_PW_OK:
+ return(GOOD_PW);
+ case KDC_PR_UNKNOWN:
+ printf("Principal %s does not exist.\n",
+ krb_unparse_name_long(myname, myinst, myrealm));
+ goto bad;
+ case GT_PW_BADPW:
+ printf("Incorrect admin password.\n");
+ goto bad;
+ default:
+ com_err("kadmin", status+krb_err_base,
+ "while getting password tickets");
+ goto bad;
+ }
+
+bad:
+ memset(admin_passwd, 0, sizeof(admin_passwd));
+ dest_tkt();
+ return(BAD_PW);
+}
+
+static void
+srvtab_put_key (int fd, char *filename, char *name, char *inst, char *realm,
+ int8_t kvno, des_cblock key)
+{
+ char sname[ANAME_SZ]; /* name of service */
+ char sinst[INST_SZ]; /* instance of service */
+ char srealm[REALM_SZ]; /* realm of service */
+ int8_t skvno;
+ des_cblock skey;
+
+ lseek(fd, 0, SEEK_SET);
+
+ while(getst(fd, sname, SNAME_SZ) > 0 &&
+ getst(fd, sinst, INST_SZ) > 0 &&
+ getst(fd, srealm, REALM_SZ) > 0 &&
+ read(fd, &skvno, sizeof(skvno)) > 0 &&
+ read(fd, skey, sizeof(skey)) > 0) {
+ if(strcmp(name, sname) == 0 &&
+ strcmp(inst, sinst) == 0 &&
+ strcmp(realm, srealm) == 0) {
+ lseek(fd, lseek(fd,0,SEEK_CUR)-(sizeof(skvno) + sizeof(skey)), SEEK_SET);
+ safe_write(filename, fd, &kvno, sizeof(kvno));
+ safe_write(filename, fd, key, sizeof(des_cblock));
+ return;
+ }
+ }
+ safe_write(filename, fd, name, strlen(name) + 1);
+ safe_write(filename, fd, inst, strlen(inst) + 1);
+ safe_write(filename, fd, realm, strlen(realm) + 1);
+ safe_write(filename, fd, &kvno, sizeof(kvno));
+ safe_write(filename, fd, key, sizeof(des_cblock));
+}
+
+/*
+ * node list of services
+ */
+
+struct srv_ent{
+ char name[SNAME_SZ];
+ char inst[INST_SZ];
+ char realm[REALM_SZ];
+ struct srv_ent *next;
+};
+
+static int
+key_to_key(char *user, char *instance, char *realm, void *arg,
+ des_cblock *key)
+{
+ memcpy(key, arg, sizeof(des_cblock));
+ return 0;
+}
+
+static void
+get_srvtab_ent(int fd, char *filename, char *name, char *inst, char *realm)
+{
+ char chname[128];
+ des_cblock newkey;
+ char old_tktfile[MaxPathLen], new_tktfile[MaxPathLen];
+ char garbage_name[ANAME_SZ];
+ char garbage_inst[ANAME_SZ];
+ CREDENTIALS c;
+ u_int8_t kvno;
+ Kadm_vals values;
+ int ret;
+
+ strncpy(chname, krb_get_phost(inst), sizeof(chname));
+ if(strcmp(inst, chname))
+ fprintf(stderr,
+ "Warning: Are you sure `%s' should not be `%s'?\n",
+ inst, chname);
+
+ memset(&values, 0, sizeof(values));
+ strcpy(values.name, name);
+ strcpy(values.instance, inst);
+ des_new_random_key(&newkey);
+ values.key_low = (newkey[0] << 24) | (newkey[1] << 16)
+ | (newkey[2] << 8) | (newkey[3] << 0);
+ values.key_high = (newkey[4] << 24) | (newkey[5] << 16)
+ | (newkey[6] << 8) | (newkey[7] << 0);
+
+ SET_FIELD(KADM_NAME,values.fields);
+ SET_FIELD(KADM_INST,values.fields);
+ SET_FIELD(KADM_DESKEY,values.fields);
+
+ ret = kadm_mod(&values, &values);
+ if(ret == KADM_NOENTRY)
+ ret = kadm_add(&values);
+ if (ret != KSUCCESS) {
+ warnx ("Couldn't get srvtab entry for %s.%s: %s",
+ name, inst, error_message(ret));
+ return;
+ }
+
+ values.key_low = values.key_high = 0;
+
+ /* get the key version number */
+
+ strcpy(old_tktfile, tkt_string());
+ snprintf(new_tktfile, sizeof(new_tktfile),
+ TKT_ROOT "_ksrvutil-get.%u",
+ (unsigned)getpid());
+ krb_set_tkt_string(new_tktfile);
+
+ ret = krb_get_in_tkt(name, inst, realm, name, inst,
+ 1, key_to_key, NULL, &newkey);
+
+ if (ret == KSUCCESS &&
+ (ret = tf_init(tkt_string(), R_TKT_FIL)) == KSUCCESS &&
+ (ret = tf_get_pname(garbage_name)) == KSUCCESS &&
+ (ret = tf_get_pinst(garbage_inst)) == KSUCCESS &&
+ (ret = tf_get_cred(&c)) == KSUCCESS)
+ kvno = c.kvno;
+ else {
+ warnx ("Could not find the cred in the ticket file");
+ return;
+ }
+
+ tf_close();
+ krb_set_tkt_string(old_tktfile);
+ unlink(new_tktfile);
+
+ if(ret != KSUCCESS) {
+ memset(&newkey, 0, sizeof(newkey));
+ warnx ("Could not get a ticket for %s: %s\n",
+ krb_unparse_name_long(name, inst, realm),
+ krb_get_err_text(ret));
+ return;
+ }
+
+ /* Write the new key & c:o to the srvtab file */
+
+ srvtab_put_key (fd, filename, name, inst, realm, kvno, newkey);
+ memset(&newkey, 0, sizeof(newkey));
+
+ fprintf (stderr, "Added %s\n", krb_unparse_name_long (name, inst, realm));
+}
+
+static void
+ksrvutil_kadm(int fd, char *filename, struct srv_ent *p)
+{
+ int ret;
+ CREDENTIALS c;
+
+ ret = kadm_init_link(PWSERV_NAME, KADM_SINST, u_realm);
+ if (ret != KADM_SUCCESS) {
+ warnx("Couldn't initialize kadmin link: %s", error_message(ret));
+ leave(NULL, 1);
+ }
+
+ ret = krb_get_cred (PWSERV_NAME, KADM_SINST, u_realm, &c);
+ if (ret == KSUCCESS)
+ des_init_random_number_generator (&c.session);
+ else {
+ umask(077);
+
+ /*
+ * create ticket file and get admin tickets
+ */
+ snprintf(tktstring, sizeof(tktstring), TKT_ROOT "_ksrvutil_%d", (int)getpid());
+ krb_set_tkt_string(tktstring);
+ destroyp = TRUE;
+
+ ret = get_admin_password(u_name, u_inst, u_realm);
+ if (ret) {
+ warnx("Couldn't get admin password.");
+ leave(NULL, 1);
+ }
+ }
+ for(;p;){
+ get_srvtab_ent(fd, filename, p->name, p->inst, p->realm);
+ p=p->next;
+ }
+ unlink(tktstring);
+}
+
+static void
+parseinput (char *result, size_t sz, char *val, char *def)
+{
+ char *lim;
+ int inq;
+
+ if (val[0] == '\0') {
+ strncpy (result, def, sz-1);
+ return;
+ }
+ lim = result + sz - 1;
+ inq = 0;
+ while(*val && result < lim) {
+ switch(*val) {
+ case '\'' :
+ inq = !inq;
+ ++val;
+ break;
+ case '\\' :
+ if(!inq)
+ val++;
+ default:
+ *result++ = *val++;
+ break;
+ }
+ }
+ *result = '\0';
+}
+
+void
+ksrvutil_get(int fd, char *filename, int argc, char **argv)
+{
+ char sname[ANAME_SZ]; /* name of service */
+ char sinst[INST_SZ]; /* instance of service */
+ char srealm[REALM_SZ]; /* realm of service */
+ char databuf[BUFSIZ];
+ char local_hostname[100];
+ char prompt[100];
+ struct srv_ent *head=NULL;
+ int i;
+
+ k_gethostname(local_hostname, sizeof(local_hostname));
+ strcpy(local_hostname, krb_get_phost(local_hostname));
+
+ if (argc)
+ for(i=0; i < argc; ++i) {
+ struct srv_ent *p=malloc(sizeof(*p));
+
+ if(p == NULL) {
+ warnx ("out of memory in malloc");
+ leave(NULL,1);
+ }
+ p->next = head;
+ strcpy (p->realm, u_realm);
+ if (kname_parse (p->name, p->inst, p->realm, argv[i]) !=
+ KSUCCESS) {
+ warnx ("parse error on '%s'\n", argv[i]);
+ free(p);
+ continue;
+ }
+ if (p->name[0] == '\0')
+ strcpy(p->name, "rcmd");
+ if (p->inst[0] == '\0')
+ strcpy(p->inst, local_hostname);
+ if (p->realm[0] == '\0')
+ strcpy(p->realm, u_realm);
+ head = p;
+ }
+
+ else
+ do{
+ safe_read_stdin("Name [rcmd]: ", databuf, sizeof(databuf));
+ parseinput (sname, sizeof(sname), databuf, "rcmd");
+
+ snprintf(prompt, sizeof(prompt), "Instance [%s]: ", local_hostname);
+ safe_read_stdin(prompt, databuf, sizeof(databuf));
+ parseinput (sinst, sizeof(sinst), databuf, local_hostname);
+
+ snprintf(prompt, sizeof(prompt), "Realm [%s]: ", u_realm);
+ safe_read_stdin(prompt, databuf, sizeof(databuf));
+ parseinput (srealm, sizeof(srealm), databuf, u_realm);
+
+ if(yn("Is this correct?")){
+ struct srv_ent *p=(struct srv_ent*)malloc(sizeof(struct srv_ent));
+ p->next=head;
+ head=p;
+ strcpy(p->name, sname);
+ strcpy(p->inst, sinst);
+ strcpy(p->realm, srealm);
+ }
+ }while(ny("Add more keys?"));
+
+
+ ksrvutil_kadm(fd, filename, head);
+
+ {
+ struct srv_ent *p=head, *q;
+ while(p){
+ q=p;
+ p=p->next;
+ free(q);
+ }
+ }
+
+}
OpenPOWER on IntegriCloud