#include <krb5.h>
#include <stdio.h>
#include <unistd.h>
#include <string.h>

#define AUTH_SUCCESS 0
#define AUTH_FAIL    1
#define AUTH_ERROR   2

/*
 * A simple Kerberos 5 example to authenticate a user/password pair
 */

int krb5auth(char *user, char *pass) {
    int ret = AUTH_SUCCESS;
    int free_creds = 1;
    krb5_context context = 0;
    krb5_principal princ = 0;
    krb5_creds creds;

    if (krb5_init_context(&context)) {
        printf("Error creating krb5 context.\n");
        ret = AUTH_ERROR;
        goto cleanup;
    }

    if (krb5_parse_name(context, user, &princ)) {
        printf("Error krb5_parse_name()\n");
        ret = AUTH_ERROR;
        goto cleanup;
    }
    if (krb5_get_init_creds_password(context, &creds, princ, pass,
         krb5_prompter_posix, NULL, 0, NULL, NULL)) {
        printf("krb5_get_init_creds_password() error or bad login\n");
        ret = AUTH_FAIL;
        free_creds = 0;
    }

cleanup:
    printf("Freeing cred contents...\n");
    if (free_creds) krb5_free_cred_contents(context, &creds);
    printf("Freeing principal...\n");
    if (princ) krb5_free_principal(context, princ);
    printf("Freeing krb5 context...\n");
    if (context) krb5_free_context(context);

    return ret;
}

void chop(char *s) {
    int i;
    i = strlen(s) - 1;
    if (s[i] == '\n')
        s[i] = '\0';
}

int main(int argc, char **argv) {
    char    pass[256];
    char    user[256];
    char    *t;

    printf("Example Kerberos 5 authentication program.\n");
    printf("Username: ");
    fgets(user, 255, stdin);
    chop(user);

    t = getpass("Password: ");
    strncpy(pass, t, 255);
    chop(pass);

    return krb5auth(user, pass);
}

