#if 1 /* temporary failsafe */

void ksrvutil_get(void)
{
}

#else /* to end of file */


#include "kadm_locl.h"
#include "ksrvutil.h"

RCSID("$Header: /afs/nada.kth.se/src/packages/kth-krb/SourceRepository/krb4/kadmin/ksrvutil_get.c,v 1.2 1995/10/27 10:56:41 bg 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, "krbtgt", 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) {
    sprintf(buf, "Password for %s.%s@%s:", 
	    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);
    bzero(admin_passwd, sizeof(admin_passwd));
    
    /* Initialize non shared random sequence from session key. */
    bzero(&c, 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.%s@%s does not exist.\n", 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:
  bzero(admin_passwd, sizeof(admin_passwd));
  (void) dest_tkt();
  return(BAD_PW);
}




/* 
 * node list of services 
 */

struct srv_ent{
  char name[SNAME_SZ];
  char inst[INST_SZ];
  char realm[REALM_SZ];
  struct srv_ent *next;
};


int get_srvtab_ent(FILE *F, char *name, char *inst, char *realm)
{
  char chname[128];

  Kadm_vals values;
  int ret;

  strncpy(chname, krb_get_phost(inst), sizeof(chname));
  if(strcmp(inst, chname))
    fprintf(stderr, "Warning: hostname '%s' changed to '%s'\n", inst, chname);
    
  
  ret=kadm_change_srvtab(name, inst, &values);
  if(ret != KSUCCESS){
    fprintf(stderr, "Couldn't get srvtab entry for %s.%s: %s\n",
	    name, inst, krb_err_txt[ret]);
  }
  
  /* convert to host order */
  values.key_low = ntohl(values.key_low);
  values.key_high = ntohl(values.key_high);
    
  fwrite(values.name, strlen(values.name) + 1, 1, F);
  fwrite(values.instance, strlen(values.instance) + 1, 1, F);
  fwrite(realm, strlen(realm) + 1, 1, F);
  /* Note: really max_lifetime is really key_version */
  fwrite(&values.max_life, sizeof(values.max_life), 1, F);
  fwrite(&values.key_low, sizeof(u_int32_t), 1, F);
  fwrite(&values.key_high, sizeof(u_int32_t), 1, F);
  values.key_low = values.key_high = 0;

  fprintf (stderr, "Written %s.%s\n", name, inst);
}


void ksrvutil_kadm(struct srv_ent *p)
{
  int ret;
  
  char krb_master[128];

  ret=krb_get_admhst(krb_master, u_realm, 1);
  if(ret != KSUCCESS){
    fprintf(stderr, "%s: Couldn't find master server: %s\n", 
	    progname, krb_err_txt[ret]);
    exit(1);
  }
  ret = kadm_init_link(PWSERV_NAME, krb_master, u_realm);
  if (ret != KADM_SUCCESS) {
    fprintf(stderr, "%s: Couldn't initialize kadmin link: %s\n",
	    progname, krb_err_txt[ret]);
    exit(1);
  }
  
  umask(077);
  
  /*
   *  create ticket file and get admin tickets
   */
  sprintf(tktstring, "/tmp/tkt_adm_%d", getpid());
  krb_set_tkt_string(tktstring);
  


  ret = get_admin_password(u_name, "root", u_realm);
  if (ret) {
    fprintf(stderr, "%s: Couldn't get admin password.\n",
	    progname);
    leave(NULL, 1);
  }
  
  {
    char fname[1024];
    FILE *F;
    struct srv_ent *q;
    sprintf(fname, "%s-new-srvtab", p->inst);
    
    unlink(fname);
    
    if ((F = fopen(fname, "w")) == NULL) {
      fprintf(stderr, "Couldn't create file '%s'.\n", fname);
      return;
    }
    
    for(;p;){
      get_srvtab_ent(F, p->name, p->inst, p->realm);
      q=p;
      p=p->next;
      free(q);
    }
    fclose(F);
    chmod(fname, 0400);
  }
}


void ksrvutil_get(void)
{
  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_realm[REALM_SZ];	/* local kerberos realm */
  char local_hostname[100];
  char prompt[100];
  struct srv_ent *head=NULL;

  if (krb_get_lrealm(local_realm, 1) != KSUCCESS)
    strcpy(local_realm, "NO.DEFAULT.REALM");
  k_gethostname(local_hostname, sizeof(local_hostname));
  strcpy(local_hostname, krb_get_phost(local_hostname));

  do{
    safe_read_stdin("Name [rcmd]: ", databuf, sizeof(databuf));
    if(databuf[0])
      strncpy(sname, databuf, sizeof(sname)-1);
    else
      strcpy(sname, "rcmd");
    
    sprintf(prompt, "Instance [%s]: ", local_hostname);
    safe_read_stdin(prompt, databuf, sizeof(databuf));
    if (databuf[0])
      strncpy(sinst, databuf, sizeof(sinst) - 1);
    else
      strcpy(sinst, local_hostname);
    
    sprintf(prompt, "Realm [%s]: ", local_realm);
    safe_read_stdin(prompt, databuf, sizeof(databuf));
    if (databuf[0])
      strncpy(srealm, databuf, sizeof(srealm) - 1);
    else
      strcpy(srealm, local_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(head);

  {
    struct srv_ent *p=head, *q;
    while(p){
      printf("%s.%s@%s\n", p->name, p->inst, p->realm);
      q=p;
      p=p->next;
      free(q);
    }
  }

/*
  do {
    do {
      safe_read_stdin("Name [rcmd]: ", databuf, sizeof(databuf));
      if (databuf[0])
	strncpy(sname, databuf, sizeof(sname) - 1);
      else
	strcpy(sname, "rcmd");

      sprintf(prompt, "Instance [%s]: ", local_hostname);
      safe_read_stdin(prompt, databuf, sizeof(databuf));
      if (databuf[0])
	strncpy(sinst, databuf, sizeof(sinst) - 1);
      else
	strcpy(sinst, local_hostname);

      sprintf(prompt, "Realm [%s]: ", local_realm);
      safe_read_stdin(prompt, databuf, sizeof(databuf));
      if (databuf[0])
	strncpy(srealm, databuf, sizeof(srealm) - 1);
      else
	strcpy(srealm, local_realm);

      printf("New principal: ");
      print_name(sname, sinst, srealm);
      
    } while (!yn("Is this correct?"));
    printf("NOT adding anything!!! Key successfully added.\n");
  } while (yn("Would you like to add another key?"));
  */
}

#endif
