/* Called at startup to grab user, instance, and realm information
   from the user's ticketfile (remember, name.inst@realm). Since we're
   using tf_get_pname(), this should work even if your kerberos username
   isn't the same as your local username. We grab the ticket at startup
   time so that even if your ticketfile dies while the screen's locked
   we'll still have the information to unlock it.

   Problems: the password dialog currently displays local username, so if
     you have some non-standard name/instance when you run xscreensaver,
     you'll need to remember what it was when unlocking, or else you lose.

     Also, we use des_string_to_key(), so if you have an AFS password
     (encrypted with ka_StringToKey()), you'll lose. Get a kerberos password;
     it isn't that hard.

   Like the original lock_init, we return false if something went wrong.
   We don't use the arguments we're given, though.
 */
Bool
kerberos_lock_init (int argc, char **argv, Bool verbose_p)
{
# ifdef HAVE_DARWIN

    KLBoolean found;
    return ((klNoErr == (KLCacheHasValidTickets (NULL, kerberosVersion_Any,
                                                 &found, &princ, NULL)))
            && found);

# else /* !HAVE_DARWIN */

    /* Perhaps we should be doing it the Mac way (above) all the time?
       The following code assumes Unix-style file-based Kerberos credentials
       cache, which Mac OS X doesn't use.  But is there any real reason to
       do it this way at all, even on other Unixen?
     */
    int k_errno;
    
    memset(name, 0, sizeof(name));
    memset(inst, 0, sizeof(inst));
    
    /* find out where the user's keeping his tickets.
       squirrel it away for later use. */
    tk_file = tkt_string();

    /* open ticket file or die trying. */
    if ((k_errno = tf_init(tk_file, R_TKT_FIL))) {
	return False;
    }

    /* same with principal and instance names */
    if ((k_errno = tf_get_pname(name)) ||
	(k_errno = tf_get_pinst(inst))) {
	return False;
    }

    /* close the ticketfile to release the lock on it. */
    tf_close();

    /* figure out what realm we're authenticated to. this ought
       to be the local realm, but it pays to be sure. */
    if ((k_errno = krb_get_tf_realm(tk_file, realm))) {
	return False;
    }

    /* last-minute sanity check on what we got. */
    if ((strlen(name)+strlen(inst)+strlen(realm)+3) >
	(REALM_SZ + ANAME_SZ + INST_SZ + 3)) {
	return False;
    }

    /* success */
    return True;

# endif /* !HAVE_DARWIN */
}
Exemple #2
0
char *
ldap_get_kerberosv4_credentials(
	LDAP *ld,
	LDAP_CONST char *who,
	LDAP_CONST char *service,
	ber_len_t *len )
{
	KTEXT_ST	ktxt;
	int		err;
	char		realm[REALM_SZ], *cred, *krbinstance;

	Debug( LDAP_DEBUG_TRACE, "ldap_get_kerberosv4_credentials\n", 0, 0, 0 );

	if ( (err = krb_get_tf_realm( tkt_string(), realm )) != KSUCCESS ) {
		Debug( LDAP_DEBUG_ANY, "ldap_get_kerberosv4_credentials: "
			"krb_get_tf_realm failed: %s\n", krb_err_txt[err], 0, 0 );
		ld->ld_errno = LDAP_AUTH_UNKNOWN;
		return( NULL );
	}

	err = 0;
#ifdef LDAP_R_COMPILE
	ldap_pvt_thread_mutex_lock( &ld->ld_req_mutex );
#endif
	if ( ber_sockbuf_ctrl( ld->ld_sb, LBER_SB_OPT_GET_FD, NULL ) == -1 ) {
		/* not connected yet */
		err = ldap_open_defconn( ld );
	}
#ifdef LDAP_R_COMPILE
	ldap_pvt_thread_mutex_unlock( &ld->ld_req_mutex );
#endif
	if ( err < 0 ) return NULL;

	krbinstance = ld->ld_defconn->lconn_krbinstance;

	if ( (err = krb_mk_req( &ktxt, service, krbinstance, realm, 0 ))
	    != KSUCCESS )
	{
		Debug( LDAP_DEBUG_ANY, "ldap_get_kerberosv4_credentials: "
			"krb_mk_req failed (%s)\n", krb_err_txt[err], 0, 0 );
		ld->ld_errno = LDAP_AUTH_UNKNOWN;
		return( NULL );
	}

	if ( ( cred = LDAP_MALLOC( ktxt.length )) == NULL ) {
		ld->ld_errno = LDAP_NO_MEMORY;
		return( NULL );
	}

	*len = ktxt.length;
	AC_MEMCPY( cred, ktxt.dat, ktxt.length );

	return( cred );
}
Exemple #3
0
char *
get_kerberosv4_credentials( LDAP *ld, char *who, char *service, int *len )
{
	KTEXT_ST	ktxt;
	int		err;
	char		realm[REALM_SZ], *cred, *krbinstance;

	Debug( LDAP_DEBUG_TRACE, catgets(slapdcat, 1, 191, "get_kerberosv4_credentials\n"), 0, 0, 0 );

	if ( (err = krb_get_tf_realm( tkt_string(), realm )) != KSUCCESS ) {
#ifndef NO_USERINTERFACE
		fprintf( stderr, "krb_get_tf_realm failed (%s)\n",
		    krb_err_txt[err] );
#endif /* NO_USERINTERFACE */
		ld->ld_errno = LDAP_INVALID_CREDENTIALS;
		return( NULL );
	}

#ifdef LDAP_REFERRALS
	krbinstance = ld->ld_defconn->lconn_krbinstance;
#else /* LDAP_REFERRALS */
	krbinstance = ld->ld_host;
#endif /* LDAP_REFERRALS */

	if ( (err = krb_mk_req( &ktxt, service, krbinstance, realm, 0 ))
	    != KSUCCESS ) {
#ifndef NO_USERINTERFACE
		fprintf( stderr, "krb_mk_req failed (%s)\n", krb_err_txt[err] );
#endif /* NO_USERINTERFACE */
		ld->ld_errno = LDAP_INVALID_CREDENTIALS;
		return( NULL );
	}

	if ( ( cred = malloc( ktxt.length )) == NULL ) {
		ld->ld_errno = LDAP_NO_MEMORY;
		return( NULL );
	}

	*len = ktxt.length;
	memcpy( cred, ktxt.dat, ktxt.length );

	return( cred );
}
Exemple #4
0
/*
* Log to a cell.  If the cell has already been logged to, return without
* doing anything.  Otherwise, log to it and mark that it has been logged
* to.  */
static int auth_to_cell(krb5_context context, char *cell, char *realm)
{
    int status = AKLOG_SUCCESS;
    char username[BUFSIZ];	  /* To hold client username structure */

    char name[ANAME_SZ];	  /* Name of afs key */
    char instance[INST_SZ];	  /* Instance of afs key */
    char realm_of_user[REALM_SZ]; /* Kerberos realm of user */
    char realm_of_cell[REALM_SZ]; /* Kerberos realm of cell */
    char local_cell[MAXCELLCHARS+1];
    char cell_to_use[MAXCELLCHARS+1]; /* Cell to authenticate to */

    krb5_creds *v5cred = NULL;
#ifdef HAVE_KRB4
    CREDENTIALS c;
#endif
    struct ktc_principal aserver;
    struct ktc_principal aclient;
    struct ktc_token atoken, btoken;
    struct afsconf_cell ak_cellconfig; /* General information about the cell */
    int i;
    int getLinkedCell = 0;

    /* try to avoid an expensive call to get_cellconfig */
    if (cell && ll_string_check(&authedcells, cell))
    {
        if (dflag)
            printf("Already authenticated to %s (or tried to)\n", cell);
        return(AKLOG_SUCCESS);
    }

    memset(name, 0, sizeof(name));
    memset(instance, 0, sizeof(instance));
    memset(realm_of_user, 0, sizeof(realm_of_user));
    memset(realm_of_cell, 0, sizeof(realm_of_cell));
    memset(&ak_cellconfig, 0, sizeof(ak_cellconfig));

    /* NULL or empty cell returns information on local cell */
    if (status = get_cellconfig(cell, &ak_cellconfig, local_cell))
        return(status);

  linkedCell:
    if (getLinkedCell)
        strncpy(cell_to_use, ak_cellconfig.linkedCell, MAXCELLCHARS);
    else
        strncpy(cell_to_use, ak_cellconfig.name, MAXCELLCHARS);
    cell_to_use[MAXCELLCHARS] = 0;

    if (ll_string_check(&authedcells, cell_to_use))
    {
        if (dflag)
            printf("Already authenticated to %s (or tried to)\n", cell_to_use);
        status = AKLOG_SUCCESS;
        goto done2;
    }

    /*
     * Record that we have attempted to log to this cell.  We do this
     * before we try rather than after so that we will not try
     * and fail repeatedly for one cell.
     */
    (void)ll_add_string(&authedcells, cell_to_use);

    if (dflag)
        printf("Authenticating to cell %s.\n", cell_to_use);

    /* We use the afs.<cellname> convention here... */
    strcpy(name, AFSKEY);
    strncpy(instance, cell_to_use, sizeof(instance));
    instance[sizeof(instance)-1] = '\0';

    /*
     * Extract the session key from the ticket file and hand-frob an
     * afs style authenticator.
     */

    if (usev5) 
    { /* using krb5 */
        int retry = 1;
	int realm_fallback = 0;

        if ((status = get_v5_user_realm(context, realm_of_user)) != KSUCCESS) {
            char * msg;
            
            if (pkrb5_get_error_message)
                msg = pkrb5_get_error_message(context, status);
            else
                msg = (char *)error_message(status);
            fprintf(stderr, "%s: Couldn't determine realm of user: %s\n",
                     progname, msg);
            if (pkrb5_free_error_message)
                pkrb5_free_error_message(context, msg);
            status = AKLOG_KERBEROS;
            goto done;
        }

        if ( strchr(name,'.') != NULL ) {
            fprintf(stderr, "%s: Can't support principal names including a dot.\n",
                    progname);
            status = AKLOG_MISC;
            goto done;
        }

      try_v5:
	if (realm && realm[0]) {
            if (dflag)
                printf("Getting v5 tickets: %s/%s@%s\n", name, instance, realm);
            status = get_v5cred(context, name, instance, realm, 
#ifdef HAVE_KRB4
                            use524 ? &c : NULL, 
#else
                            NULL,
#endif
                            &v5cred);
            strcpy(realm_of_cell, realm);
        } else {
	    strcpy(realm_of_cell,
		    afs_realm_of_cell5(context, &ak_cellconfig, realm_fallback));

            if (retry == 1 && realm_fallback == 0) {
                /* Only try the realm_of_user once */
                status = -1;
                if (dflag)
                    printf("Getting v5 tickets: %s/%s@%s\n", name, instance, realm_of_user);
                status = get_v5cred(context, name, instance, realm_of_user, 
#ifdef HAVE_KRB4
                                     use524 ? &c : NULL, 
#else
                                     NULL,
#endif
                                     &v5cred);
                if (status == 0) {
                    /* we have determined that the client realm 
                     * is a valid cell realm
                     */
                    strcpy(realm_of_cell, realm_of_user);
                }
            }

            if (status != 0 && (!retry || retry && strcmp(realm_of_user,realm_of_cell))) {
                if (dflag)
                    printf("Getting v5 tickets: %s/%s@%s\n", name, instance, realm_of_cell);
                status = get_v5cred(context, name, instance, realm_of_cell, 
#ifdef HAVE_KRB4
                                     use524 ? &c : NULL, 
#else
                                     NULL,
#endif
                                     &v5cred);
                if (!status && !strlen(realm_of_cell)) 
                    copy_realm_of_ticket(context, realm_of_cell, sizeof(realm_of_cell), v5cred);
            }
        }

	if (!realm_fallback && status == KRB5_ERR_HOST_REALM_UNKNOWN) {
	    realm_fallback = 1;
	    goto try_v5;
	} else if (status == KRB5KDC_ERR_S_PRINCIPAL_UNKNOWN) {
	    if (!realm_fallback && !realm_of_cell[0]) {
		realm_fallback = 1;
		goto try_v5;
	    }
            if (dflag)
                printf("Getting v5 tickets: %s@%s\n", name, realm_of_cell);
            status = get_v5cred(context, name, "", realm_of_cell, 
#ifdef HAVE_KRB4
                                use524 ? &c : NULL, 
#else
                                NULL,
#endif
                                &v5cred);
            if (!status && !strlen(realm_of_cell)) 
                copy_realm_of_ticket(context, realm_of_cell, sizeof(realm_of_cell), v5cred);
	}
     
        if ( status == KRB5KRB_AP_ERR_MSG_TYPE && retry ) {
            retry = 0;
	    realm_fallback = 0;
            goto try_v5;
        }       
    }       
    else 
    {
#ifdef HAVE_KRB4
	if (realm && realm[0])
	    strcpy(realm_of_cell, realm);
	else
	    strcpy(realm_of_cell, afs_realm_of_cell(&ak_cellconfig));

	/*
         * Try to obtain AFS tickets.  Because there are two valid service
         * names, we will try both, but trying the more specific first.
         *
         * 	afs.<cell>@<realm>
         * 	afs@<realm>
         */
        if (dflag)
            printf("Getting tickets: %s.%s@%s\n", name, instance, realm_of_cell);
        status = get_cred(name, instance, realm_of_cell, &c);
        if (status == KDC_PR_UNKNOWN)
        {
            if (dflag)
                printf("Getting tickets: %s@%s\n", name, realm_of_cell);
            status = get_cred(name, "", realm_of_cell, &c);
        }
#else
        status = AKLOG_MISC;
        goto done;
#endif
    } 

    if (status != KSUCCESS)
    {
        char * msg = NULL;
        if (dflag)
            printf("Kerberos error code returned by get_cred: %d\n", status);

        if (usev5) {
            if (pkrb5_get_error_message)
                msg = pkrb5_get_error_message(context, status);
            else
                msg = (char *)error_message(status);
        }
#ifdef HAVE_KRB4
        else
            msg = krb_err_text(status);
#endif
        fprintf(stderr, "%s: Couldn't get %s AFS tickets: %s\n",
                 progname, cell_to_use, msg?msg:"(unknown error)");
        if (usev5 && pkrb5_free_error_message)
            pkrb5_free_error_message(context, msg);
        status = AKLOG_KERBEROS;
        goto done;
    }

    strncpy(aserver.name, AFSKEY, MAXKTCNAMELEN - 1);
    strncpy(aserver.instance, AFSINST, MAXKTCNAMELEN - 1);
    strncpy(aserver.cell, cell_to_use, MAXKTCREALMLEN - 1);

    if (usev5 && !use524) {
        /* This code inserts the entire K5 ticket into the token
         * No need to perform a krb524 translation which is
         * commented out in the code below
         */
        char * p;
        int len;
        
        len = min(v5cred->client->data[0].length,MAXKTCNAMELEN - 1);
        strncpy(username, v5cred->client->data[0].data, len);
        username[len] = '\0';

        if ( v5cred->client->length > 1 ) {
            strcat(username, ".");
            p = username + strlen(username);
            len = min(v5cred->client->data[1].length, (unsigned int)(MAXKTCNAMELEN - strlen(username) - 1));
            strncpy(p, v5cred->client->data[1].data, len);
            p[len] = '\0';
        }

        memset(&atoken, '\0', sizeof(atoken));
        atoken.kvno = RXKAD_TKT_TYPE_KERBEROS_V5;
        atoken.startTime = v5cred->times.starttime;
        atoken.endTime = v5cred->times.endtime;
        memcpy(&atoken.sessionKey, v5cred->keyblock.contents, v5cred->keyblock.length);
        atoken.ticketLen = v5cred->ticket.length;
        memcpy(atoken.ticket, v5cred->ticket.data, atoken.ticketLen);
    } else {
#ifdef HAVE_KRB4
        strcpy (username, c.pname);
        if (c.pinst[0])
        {
            strcat(username, ".");
            strcat(username, c.pinst);
        }

        atoken.kvno = c.kvno;
        atoken.startTime = c.issue_date;
        /* ticket lifetime is in five-minutes blocks. */
        atoken.endTime = c.issue_date + ((unsigned char)c.lifetime * 5 * 60);

        memcpy(&atoken.sessionKey, c.session, 8);
        atoken.ticketLen = c.ticket_st.length;
        memcpy(atoken.ticket, c.ticket_st.dat, atoken.ticketLen);
#else
        status = AKLOG_MISC;
        goto done;
#endif
    }

    if (!force &&
         !ktc_GetToken(&aserver, &btoken, sizeof(btoken), &aclient) &&
         atoken.kvno == btoken.kvno &&
         atoken.ticketLen == btoken.ticketLen &&
         !memcmp(&atoken.sessionKey, &btoken.sessionKey, sizeof(atoken.sessionKey)) &&
         !memcmp(atoken.ticket, btoken.ticket, atoken.ticketLen))
    {       
        if (dflag)
            printf("Identical tokens already exist; skipping.\n");
        status = AKLOG_SUCCESS;
        goto done2;
    }

    if (noprdb)
    {
        if (dflag)
            printf("Not resolving name %s to id (-noprdb set)\n", username);
    }       
    else    
    {
        if (!usev5) {
#ifdef HAVE_KRB4
            if ((status = krb_get_tf_realm(TKT_FILE, realm_of_user)) != KSUCCESS)
            {
                fprintf(stderr, "%s: Couldn't determine realm of user: %s)",
                         progname, krb_err_text(status));
                status = AKLOG_KERBEROS;
                goto done;
            }
#else
            status = AKLOG_MISC;
            goto done;
#endif
        }

        /* For Network Identity Manager append the realm to the name */
        strcat(username, "@");
        strcat(username, realm_of_user);

        ViceIDToUsername(username, realm_of_user, realm_of_cell, cell_to_use, 
#ifdef HAVE_KRB4
                          &c, 
#else
                          NULL,
#endif
                          &status, &aclient, &aserver, &atoken);
    }

    if (dflag)
        printf("Set username to %s\n", username);

    /* Reset the "aclient" structure before we call ktc_SetToken.
     * This structure was first set by the ktc_GetToken call when
     * we were comparing whether identical tokens already existed.
     */
    strncpy(aclient.name, username, MAXKTCNAMELEN - 1);
    strcpy(aclient.instance, "");
    
    if (usev5 && !use524) {
        int len = min(v5cred->client->realm.length,MAXKTCNAMELEN - 1);
        strncpy(aclient.cell, v5cred->client->realm.data, len);
        aclient.cell[len] = '\0';
    } 
#ifdef HAVE_KRB4
    else
	strncpy(aclient.cell, c.realm, MAXKTCREALMLEN - 1);
#endif

    for ( i=0; aclient.cell[i]; i++ ) {
        if ( islower(aclient.cell[i]) )
            aclient.cell[i] = toupper(aclient.cell[i]);
    }

    if (dflag)
        printf("Getting tokens.\n");
    if (status = ktc_SetToken(&aserver, &atoken, &aclient, 0))
    {
        afs_com_err(progname, status,
                     "while obtaining tokens for cell %s\n",
                     cell_to_use);
        status = AKLOG_TOKEN;
    }

  done2:
    if (ak_cellconfig.linkedCell && !getLinkedCell) {
        getLinkedCell = 1;
        goto linkedCell;
    }

  done:
#if 0
    /* 
     * intentionally leak the linkedCell field because it was allocated
     * using a different C RTL version.
     */
    if (ak_cellconfig.linkedCell)
        free(ak_cellconfig.linkedCell);
#endif
    return(status);
}
Exemple #5
0
/*
 * Log to a cell.  If the cell has already been logged to, return without
 * doing anything.  Otherwise, log to it and mark that it has been logged
 * to.  */
static int auth_to_cell(char *cell, char *realm)
{
  int status = AKLOG_SUCCESS;
  char username[BUFSIZ];	/* To hold client username structure */
  long viceId;			/* AFS uid of user */

  char name[ANAME_SZ];		/* Name of afs key */
  char instance[INST_SZ];	/* Instance of afs key */
  char realm_of_user[REALM_SZ]; /* Kerberos realm of user */
  char realm_of_cell[REALM_SZ]; /* Kerberos realm of cell */
  char local_cell[MAXCELLCHARS+1];
  char cell_to_use[MAXCELLCHARS+1]; /* Cell to authenticate to */

  int i,j;

  CREDENTIALS c;
  struct ktc_principal aserver;
  struct ktc_principal aclient;
  struct ktc_token atoken, btoken;

  /* try to avoid an expensive call to get_cellconfig */
  if (cell && ll_string_check(&authedcells, cell))
    {
      if (dflag)
	printf("Already authenticated to %s (or tried to)\n", cell);
      return(AKLOG_SUCCESS);
    }

  memset(name, 0, sizeof(name));
  memset(instance, 0, sizeof(instance));
  memset(realm_of_user, 0, sizeof(realm_of_user));
  memset(realm_of_cell, 0, sizeof(realm_of_cell));

  /* NULL or empty cell returns information on local cell */
  if (status = get_cellconfig(cell, &ak_cellconfig, local_cell))
    return(status);

  strncpy(cell_to_use, ak_cellconfig.name, MAXCELLCHARS);
  cell_to_use[MAXCELLCHARS] = 0;

  if (ll_string_check(&authedcells, cell_to_use))
    {
      if (dflag)
	printf("Already authenticated to %s (or tried to)\n", cell_to_use);
      return(AKLOG_SUCCESS);
    }

  /*
   * Record that we have attempted to log to this cell.  We do this
   * before we try rather than after so that we will not try
   * and fail repeatedly for one cell.
   */
  (void)ll_add_string(&authedcells, cell_to_use);

  if (dflag)
    printf("Authenticating to cell %s.\n", cell_to_use);

  if (realm && realm[0])
    strcpy(realm_of_cell, realm);
  else
    strcpy(realm_of_cell, afs_realm_of_cell(&ak_cellconfig));

  /* We use the afs.<cellname> convention here... */
  strcpy(name, AFSKEY);
  strncpy(instance, cell_to_use, sizeof(instance));
  instance[sizeof(instance)-1] = '\0';

  /*
   * Extract the session key from the ticket file and hand-frob an
   * afs style authenticator.
   */

  /*
   * Try to obtain AFS tickets.  Because there are two valid service
   * names, we will try both, but trying the more specific first.
   *
   * 	afs.<cell>@<realm>
   * 	afs@<realm>
   */
  if (dflag)
    printf("Getting tickets: %s.%s@%s\n", name, instance, realm_of_cell);
  status = get_cred(name, instance, realm_of_cell, &c);
  if (status == KDC_PR_UNKNOWN)
    {
      if (dflag)
	printf("Getting tickets: %s@%s\n", name, realm_of_cell);
      status = get_cred(name, "", realm_of_cell, &c);
    }

  if (status != KSUCCESS)
    {
      if (dflag)
	printf("Kerberos error code returned by get_cred: %d\n", status);
      fprintf(stderr, "%s: Couldn't get %s AFS tickets: %s\n",
	      progname, cell_to_use, krb_err_txt[status]);
      return(AKLOG_KERBEROS);
    }

  strncpy(aserver.name, AFSKEY, MAXKTCNAMELEN - 1);
  strncpy(aserver.instance, AFSINST, MAXKTCNAMELEN - 1);
  strncpy(aserver.cell, cell_to_use, MAXKTCREALMLEN - 1);

  strcpy (username, c.pname);
  if (c.pinst[0])
    {
      strcat(username, ".");
      strcat(username, c.pinst);
    }

  atoken.kvno = c.kvno;
  atoken.startTime = c.issue_date;
  /* ticket lifetime is in five-minutes blocks. */
  atoken.endTime = c.issue_date + ((unsigned char)c.lifetime * 5 * 60);
  memcpy(&atoken.sessionKey, c.session, 8);
  atoken.ticketLen = c.ticket_st.length;
  memcpy(atoken.ticket, c.ticket_st.dat, atoken.ticketLen);

  if (!force &&
      !ktc_GetToken(&aserver, &btoken, sizeof(btoken), &aclient) &&
      atoken.kvno == btoken.kvno &&
      atoken.ticketLen == btoken.ticketLen &&
      !memcmp(&atoken.sessionKey, &btoken.sessionKey, sizeof(atoken.sessionKey)) &&
      !memcmp(atoken.ticket, btoken.ticket, atoken.ticketLen))
    {
      if (dflag)
	printf("Identical tokens already exist; skipping.\n");
      return 0;
    }

  if (noprdb)
    {
      if (dflag)
	printf("Not resolving name %s to id (-noprdb set)\n", username);
    }
  else
    {
      if ((status = krb_get_tf_realm(TKT_FILE, realm_of_user)) != KSUCCESS)
	{
	  fprintf(stderr, "%s: Couldn't determine realm of user: %s)",
		  progname, krb_err_txt[status]);
	  return(AKLOG_KERBEROS);
	}
      if (strcmp(realm_of_user, realm_of_cell))
	{
	  strcat(username, "@");
	  strcat(username, realm_of_user);
	}

      if (dflag)
	printf("About to resolve name %s to id\n", username);

      if (!pr_Initialize (0, AFSDIR_CLIENT_ETC_DIRPATH, aserver.cell))
	status = pr_SNameToId (username, &viceId);

      if (dflag)
	{
	  if (status)
	    printf("Error %d\n", status);
	  else
	    printf("Id %d\n", viceId);
	}

      /*
       * This is a crock, but it is Transarc's crock, so
       * we have to play along in order to get the
       * functionality.  The way the afs id is stored is
       * as a string in the username field of the token.
       * Contrary to what you may think by looking at
       * the code for tokens, this hack (AFS ID %d) will
       * not work if you change %d to something else.
       */
      if ((status == 0) && (viceId != ANONYMOUSID))
	sprintf (username, "AFS ID %d", viceId);
    }

  if (dflag)
    printf("Set username to %s\n", username);

  /* Reset the "aclient" structure before we call ktc_SetToken.
   * This structure was first set by the ktc_GetToken call when
   * we were comparing whether identical tokens already existed.
   */
  strncpy(aclient.name, username, MAXKTCNAMELEN - 1);
  strcpy(aclient.instance, "");
  strncpy(aclient.cell, c.realm, MAXKTCREALMLEN - 1);

  if (dflag)
    printf("Getting tokens.\n");
  if (status = ktc_SetToken(&aserver, &atoken, &aclient, 0))
    {
      fprintf(stderr,
	      "%s: unable to obtain tokens for cell %s (status: %d).\n",
	      progname, cell_to_use, status);
      status = AKLOG_TOKEN;
    }

  return(status);
}
Exemple #6
0
int
krb_mk_req(KTEXT authent, char *service, char *instance, char *realm, 
	   int32_t checksum)
{
    KTEXT_ST req_st;
    KTEXT req_id = &req_st;

    CREDENTIALS cr;             /* Credentials used by retr */
    KTEXT ticket = &(cr.ticket_st); /* Pointer to tkt_st */
    int retval;                 /* Returned by krb_get_cred */

    char myrealm[REALM_SZ];

    unsigned char *p = authent->dat;
    int rem = sizeof(authent->dat);
    int tmp;

    tmp = krb_put_int(KRB_PROT_VERSION, p, rem, 1);
    if (tmp < 0)
	return KFAILURE;
    p += tmp;
    rem -= tmp;

    tmp = krb_put_int(AUTH_MSG_APPL_REQUEST, p, rem, 1);
    if (tmp < 0)
	return KFAILURE;
    p += tmp;
    rem -= tmp;

    /* Get the ticket and move it into the authenticator */
    if (krb_ap_req_debug)
        krb_warning("Realm: %s\n", realm);

    retval = krb_get_cred(service,instance,realm,&cr);

    if (retval == RET_NOTKT) {
	retval = get_ad_tkt(service, instance, realm, lifetime);
	if (retval == KSUCCESS)
	    retval = krb_get_cred(service, instance, realm, &cr);
    }

    if (retval != KSUCCESS)
	return retval;


    /*
     * With multi realm ticket files either find a matching TGT or
     * else use the first TGT for inter-realm authentication.
     *
     * In myrealm hold the realm of the principal "owning" the
     * corresponding ticket-granting-ticket.
     */

    retval = krb_get_cred(KRB_TICKET_GRANTING_TICKET, realm, realm, 0);
    if (retval == KSUCCESS) {
      strcpy_truncate(myrealm, realm, REALM_SZ);
    } else
      retval = krb_get_tf_realm(TKT_FILE, myrealm);
    
    if (retval != KSUCCESS)
	return retval;
    
    if (krb_ap_req_debug)
        krb_warning("serv=%s.%s@%s princ=%s.%s@%s\n", service, instance, realm,
		    cr.pname, cr.pinst, myrealm);

    tmp = krb_put_int(cr.kvno, p, rem, 1);
    if (tmp < 0)
	return KFAILURE;
    p += tmp;
    rem -= tmp;

    tmp = krb_put_string(realm, p, rem);
    if (tmp < 0)
	return KFAILURE;
    p += tmp;
    rem -= tmp;

    tmp = krb_put_int(ticket->length, p, rem, 1);
    if (tmp < 0)
	return KFAILURE;
    p += tmp;
    rem -= tmp;

    retval = build_request(req_id, cr.pname, cr.pinst, myrealm, checksum);
    if (retval != KSUCCESS)
	return retval;
    
    encrypt_ktext(req_id, &cr.session, DES_ENCRYPT);

    tmp = krb_put_int(req_id->length, p, rem, 1);
    if (tmp < 0)
	return KFAILURE;
    p += tmp;
    rem -= tmp;

    if (rem < ticket->length + req_id->length)
	return KFAILURE;

    memcpy(p, ticket->dat, ticket->length);
    p += ticket->length;
    rem -= ticket->length;
    memcpy(p, req_id->dat, req_id->length);
    p += req_id->length;
    rem -= req_id->length;

    authent->length = p - authent->dat;
    
    memset(&cr, 0, sizeof(cr));
    memset(&req_st, 0, sizeof(req_st));

    if (krb_ap_req_debug)
        krb_warning("Authent->length = %d\n", authent->length);

    return KSUCCESS;
}