[OpenAFS] Authentication weirdness

Charles Clancy security@xauth.net
Tue, 29 Oct 2002 22:10:09 -0600 (CST)


On Tue, 29 Oct 2002, Chris Snyder wrote:

> As I said in a previous email to this list, I'm trying to get Apache to
> do authentication using AFS. I installed the mod_auth_external module,
> along with the pwauth program, which is PAM-aware. It works fine when I
> try pwauth from the command line as root, returning 0 when the username
> and password are correct. However, when I try to run it as any other
> user, with pwauth suid, it fails, returning an error code of 1.

I've found pwauth to be extremely flaky.  When you have apache call a
script call a program call PAM call a module call Kerberos to do the
authentication, things are bound to go wrong.

Try calling the attached program directly from Apache.  (Make sure
/usr/kerberos/lib is in Apache's LD_LIBRARY_PATH).

[ t charles clancy ]--[ tclancy@uiuc.edu ]--[ www.uiuc.edu/~tclancy ]

------------------ begin krb5check.c -----------------------

/**********************************************************
  krb5check -- Accepts two lines of STDIN representing a
  username and a password.  Authenticates them against a
  Kerberos 5 server, and returns 0 if successful.

  NOTE: can specify username@REALM for username if you want

  To compile:
    gcc -I/usr/kerberos/include -c -o krb5check.o krb5check.c
    gcc -L/usr/kerberos/lib -o krb5check krb5check.o -lkrb5 -lcrypto
     (of course, add -lxnet on Solaris)

  Tested: RedHat 7.3, Solaris 8

  Author: Charles Clancy, tclancy@uiuc.edu
**********************************************************/

#include "krb5.h"
#include <stdio.h>

krb5_data tgtname = { 0, KRB5_TGS_NAME_SIZE, KRB5_TGS_NAME };

int krb5_check_password(char *username, char *password) {

    krb5_context kcontext;
    krb5_creds my_creds;

    memset((char*)&my_creds, 0, sizeof(my_creds));

    if (krb5_init_context(&kcontext)) return 1;
    if (krb5_parse_name (kcontext, username, &(my_creds.client)))
	return 1;
    if (krb5_build_principal_ext(kcontext, &my_creds.server,
	    krb5_princ_realm(kcontext, my_creds.client)->length,
	    krb5_princ_realm(kcontext, my_creds.client)->data,
	    tgtname.length, tgtname.data,
	    krb5_princ_realm(kcontext, my_creds.client)->length,
	    krb5_princ_realm(kcontext, my_creds.client)->data, 0))
		return 1;
    if (krb5_get_in_tkt_with_password(kcontext, 0, (krb5_address **)0,
	NULL, NULL, password, NULL, &my_creds, 0)) return 1;

    return 0;
}

int main(void) {

    int r;
    char username[256], password[256];

    memset(username, 0, 256);
    memset(password, 0, 256);

    fgets(username, 255, stdin);
    username[strlen(username)-1]=0; /* chomp! */
    fgets(password, 255, stdin);
    password[strlen(password)-1]=0; /* chomp! */

    r=krb5_check_password(username, password);
    memset(password, 0, 256);

    if (r) fprintf(stderr, "auth failure for %s.\n",username);
      else fprintf(stderr, "auth successful for %s.\n",username);

    return r;

}