--- /dev/null
+/*
+ * $Source$
+ * $Author$
+ *
+ * Copyright 1990 by the Massachusetts Institute of Technology.
+ *
+ * For copying and distribution information, please see the file
+ * <krb5/copyright.h>.
+ *
+ * krb5_kuserok()
+ */
+
+#if !defined(lint) && !defined(SABER)
+static char rcsid_kuserok_c [] =
+"$Id$";
+#endif /* !lint & !SABER */
+
+#include <krb5/copyright.h>
+#include <krb5/krb5.h>
+#include <krb5/ext-proto.h>
+#include <stdio.h>
+#include <krb5/libos-proto.h>
+#include <sys/types.h>
+#include <sys/param.h> /* for MAXPATHLEN */
+#include <sys/file.h>
+#include <sys/stat.h>
+#include <pwd.h>
+
+#define OK 0
+#define NOTOK 1
+#define MAX_USERNAME 10
+
+/*
+ * Given a Kerberos principal "principal", and a local username "luser",
+ * determine whether user is authorized to login according to the
+ * authorization file ("~luser/.klogin" by default). Returns OK
+ * if authorized, NOTOK if not authorized.
+ *
+ * If there is no account for "luser" on the local machine, returns
+ * NOTOK. If there is no authorization file, and the given Kerberos
+ * name "server" translates to the same name as "luser" (using
+ * krb5_aname_to_lname()), returns OK. Otherwise, if the authorization file
+ * can't be accessed, returns NOTOK. Otherwise, the file is read for
+ * a matching principal name, instance, and realm. If one is found,
+ * returns OK, if none is found, returns NOTOK.
+ *
+ * The file entries are in the format produced by krb5_unparse_name(),
+ * one entry per line.
+ *
+ */
+
+krb5_boolean
+krb5_kuserok(principal, luser)
+krb5_principal principal;
+const char *luser;
+{
+ struct stat sbuf;
+ struct passwd *pwd;
+ char pbuf[MAXPATHLEN];
+ krb5_boolean isok = FALSE;
+ FILE *fp;
+ char kuser[MAX_USERNAME];
+ char *princname;
+ char linebuf[BUFSIZ];
+ char *newline;
+ int gobble;
+
+ /* no account => no access */
+ if ((pwd = getpwnam(luser)) == NULL) {
+ return(FALSE);
+ }
+ (void) strcpy(pbuf, pwd->pw_dir);
+ (void) strcat(pbuf, "/.k5login");
+
+ if (access(pbuf, F_OK)) { /* not accessible */
+ /*
+ * if he's trying to log in as himself, and there is no .klogin file,
+ * let him. To find out, call
+ * krb5_aname_to_localname to convert the principal to a name
+ * which we can string compare.
+ */
+ if (!(krb5_aname_to_localname(principal,
+ sizeof(kuser), kuser))
+ && (strcmp(kuser, luser) == 0)) {
+ return(TRUE);
+ }
+ }
+ if (krb5_unparse_name(principal, &princname))
+ return(FALSE); /* no hope of matching */
+
+ /* open ~/.klogin */
+ if ((fp = fopen(pbuf, "r")) == NULL) {
+ free(princname);
+ return(FALSE);
+ }
+ /*
+ * security: if the user does not own his own .klogin file,
+ * do not grant access
+ */
+ if (fstat(fileno(fp), &sbuf)) {
+ fclose(fp);
+ free(princname);
+ return(FALSE);
+ }
+ if (sbuf.st_uid != pwd->pw_uid) {
+ fclose(fp);
+ free(princname);
+ return(FALSE);
+ }
+
+ /* check each line */
+ while (!isok && (fgets(linebuf, BUFSIZ, fp) != NULL)) {
+ /* null-terminate the input string */
+ linebuf[BUFSIZ-1] = '\0';
+ newline = NULL;
+ /* nuke the newline if it exists */
+ if (newline = index(linebuf, '\n'))
+ *newline = '\0';
+ if (!strcmp(linebuf, princname)) {
+ isok = TRUE;
+ continue;
+ }
+ /* clean up the rest of the line if necessary */
+ if (!newline)
+ while (((gobble = getc(fp)) != EOF) && gobble != '\n');
+ }
+ free(princname);
+ fclose(fp);
+ return(isok);
+}