Incremental checkin.
authorfredrik@DOLDA2000.COM <fredrik@DOLDA2000.COM@959494ce-11ee-0310-bf91-de5d638817bd>
Fri, 4 Mar 2005 16:09:28 +0000 (16:09 +0000)
committerfredrik@DOLDA2000.COM <fredrik@DOLDA2000.COM@959494ce-11ee-0310-bf91-de5d638817bd>
Fri, 4 Mar 2005 16:09:28 +0000 (16:09 +0000)
git-svn-id: svn+ssh://svn.dolda2000.com/srv/svn/repos/src/utils@172 959494ce-11ee-0310-bf91-de5d638817bd

pam_krb5auto.c

index cf1e5e7..8b6cfe1 100644 (file)
 #include <stdlib.h>
 #include <stdlib.h>
+#include <stdio.h>
 #include <unistd.h>
 #include <unistd.h>
+#include <string.h>
+#include <stdarg.h>
+#include <malloc.h>
 #include <krb5.h>
 
 #define PAM_SM_AUTH
 
 #include <security/pam_modules.h>
 
 #include <krb5.h>
 
 #define PAM_SM_AUTH
 
 #include <security/pam_modules.h>
 
+#define DEF_INSTANCE "autologin"
+
+struct options
+{
+    char *realm;
+    char *instance;
+    char *keytab;
+    int debug;
+};
+
+struct data
+{
+    krb5_context ctx;
+    krb5_ccache cc;
+    krb5_principal me;
+};
+
+static void log(int prio, char *format, ...)
+{
+    va_list args;
+    char buf[1024];
+    
+    va_start(args, format);
+    snprintf(buf, sizeof(buf), "pam_krb5auto[%i]: %s", getpid(), format);
+    vsyslog(prio, buf, args);
+    va_end(args);
+}
+
+static struct options *parseopts(int argc, const char **argv)
+{
+    int i;
+    struct options *opts;
+    
+    opts = malloc(sizeof(*opts));
+    memset(opts, 0, sizeof(*opts));
+    for(i = 0; i < argc; i++) {
+       if(!strncmp(argv[i], "realm=", 6))
+           opts->realm = strdup(argv[i] + 6);
+       if(!strncmp(argv[i], "instance=", 9))
+           opts->instance = strdup(argv[i] + 9);
+       if(!strncmp(argv[i], "keytab=", 7))
+           opts->keytab = strdup(argv[i] + 7);
+       if(!strcmp(argv[i], "debug"))
+           opts->debug = 1;
+    }
+    return(opts);
+}
+
+static void freeopts(struct options *opts)
+{
+    if(opts->realm != NULL)
+       free(opts->realm);
+    if(opts->instance != NULL)
+       free(opts->instance);
+    if(opts->keytab != NULL)
+       free(opts->keytab);
+    free(opts);
+}
+
+static void freedata(struct data *data)
+{
+    if(data->me != NULL)
+       krb5_free_principal(data->ctx, data->me);
+    if(data->ctx != NULL)
+       krb5_free_context(data->ctx);
+    free(data);
+}
+
+static void cleanupdata(pam_handle_t *pamh, struct data *data, int error_status)
+{
+    freedata(data);
+}
+
+static struct data *getdata(pam_handle_t *pamh, struct options *opts)
+{
+    int ret;
+    struct data *data;
+    char buf[1024];
+    const char *user, *instance;
+    
+    data = NULL;
+    pam_get_data(pamh, "krb5auto-data", (const void **)&data);
+    if(data == NULL) {
+       if(opts->debug)
+           log(LOG_DEBUG, "creating new instance");
+       data = malloc(sizeof(*data));
+       memset(data, 0, sizeof(*data));
+       if((ret = krb5_init_context(&data->ctx)) != 0) {
+           log(LOG_CRIT, "could not create krb5 context: %s", error_message(ret));
+           freedata(data);
+           return(NULL);
+       }
+       pam_get_user(pamh, &user, NULL);
+       if(opts->instance)
+           instance = opts->instance;
+       else
+           instance = DEF_INSTANCE;
+       if(opts->realm)
+           snprintf(buf, sizeof(buf), "%s/%s@%s", user, instance, opts->realm);
+       else
+           snprintf(buf, sizeof(buf), "%s/%s", user, instance);
+       if((ret = krb5_parse_name(data->ctx, buf, &data->me)) != 0) {
+           log(LOG_ERR, "could not parse principal name `%s': %s", buf, error_message(ret));
+           freedata(data);
+           return(NULL);
+       }
+       pam_set_data(pamh, "krb5auto-data", data, (void (*)(pam_handle_t *, void *, int))cleanupdata);
+    }
+    return(data);
+}
+
+static void savecreds(struct options *opts, struct data *data)
+{
+}
+
+PAM_EXTERN int pam_sm_authenticate(pam_handle_t *pamh, int flags, int argc, const char **argv)
+{
+    return(PAM_IGNORE);
+}
+
+PAM_EXTERN int pam_sm_setcred(pam_handle_t *pamh, int flags, int argc, const char **argv)
+{
+    struct options *opts;
+    struct data *data;
+    
+    opts = parseopts(argc, argv);
+    data = getdata(pamh, opts);
+    if(data == NULL) {
+       log(LOG_ERR, "could not get data, erroring out");
+       return(PAM_SERVICE_ERR);
+    }
+    if(flags & PAM_ESTABLISH_CRED) {
+       savecreds(opts, data);
+    }
+    freeopts(opts);
+    return(PAM_IGNORE);
+}
 
 /*
  * Local Variables:
 
 /*
  * Local Variables: