aboutsummaryrefslogtreecommitdiff
path: root/lib/krb5/kuserok.c
diff options
context:
space:
mode:
Diffstat (limited to 'lib/krb5/kuserok.c')
-rw-r--r--lib/krb5/kuserok.c135
1 files changed, 88 insertions, 47 deletions
diff --git a/lib/krb5/kuserok.c b/lib/krb5/kuserok.c
index 8f0ff996960d..2fe4e490aa41 100644
--- a/lib/krb5/kuserok.c
+++ b/lib/krb5/kuserok.c
@@ -1,62 +1,63 @@
/*
- * Copyright (c) 1997 - 2005 Kungliga Tekniska Högskolan
- * (Royal Institute of Technology, Stockholm, Sweden).
- * All rights reserved.
+ * Copyright (c) 1997 - 2005 Kungliga Tekniska Högskolan
+ * (Royal Institute of Technology, Stockholm, Sweden).
+ * All rights reserved.
*
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
*
- * 1. Redistributions of source code must retain the above copyright
- * notice, this list of conditions and the following disclaimer.
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
*
- * 2. Redistributions in binary form must reproduce the above copyright
- * notice, this list of conditions and the following disclaimer in the
- * documentation and/or other materials provided with the distribution.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
*
- * 3. Neither the name of the Institute nor the names of its contributors
- * may be used to endorse or promote products derived from this software
- * without specific prior written permission.
+ * 3. Neither the name of the Institute nor the names of its contributors
+ * may be used to endorse or promote products derived from this software
+ * without specific prior written permission.
*
- * THIS SOFTWARE IS PROVIDED BY THE INSTITUTE AND CONTRIBUTORS ``AS IS'' AND
- * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
- * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
- * ARE DISCLAIMED. IN NO EVENT SHALL THE INSTITUTE OR CONTRIBUTORS BE LIABLE
- * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
- * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
- * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
- * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
- * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
- * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
- * SUCH DAMAGE.
+ * THIS SOFTWARE IS PROVIDED BY THE INSTITUTE AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE INSTITUTE OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
*/
#include "krb5_locl.h"
#include <dirent.h>
-RCSID("$Id: kuserok.c 16048 2005-09-09 10:33:33Z lha $");
+#ifndef _WIN32
/* see if principal is mentioned in the filename access file, return
TRUE (in result) if so, FALSE otherwise */
static krb5_error_code
-check_one_file(krb5_context context,
- const char *filename,
+check_one_file(krb5_context context,
+ const char *filename,
struct passwd *pwd,
- krb5_principal principal,
+ krb5_principal principal,
krb5_boolean *result)
{
FILE *f;
char buf[BUFSIZ];
krb5_error_code ret;
struct stat st;
-
+
*result = FALSE;
f = fopen (filename, "r");
if (f == NULL)
return errno;
-
+ rk_cloexec_file(f);
+
/* check type and mode of file */
if (fstat(fileno(f), &st) != 0) {
fclose (f);
@@ -105,10 +106,10 @@ check_one_file(krb5_context context,
}
static krb5_error_code
-check_directory(krb5_context context,
- const char *dirname,
+check_directory(krb5_context context,
+ const char *dirname,
struct passwd *pwd,
- krb5_principal principal,
+ krb5_principal principal,
krb5_boolean *result)
{
DIR *d;
@@ -124,16 +125,15 @@ check_directory(krb5_context context,
if (!S_ISDIR(st.st_mode))
return ENOTDIR;
-
+
if (st.st_uid != pwd->pw_uid && st.st_uid != 0)
return EACCES;
if ((st.st_mode & (S_IWGRP | S_IWOTH)) != 0)
return EACCES;
- if((d = opendir(dirname)) == NULL)
+ if((d = opendir(dirname)) == NULL)
return errno;
-#ifdef HAVE_DIRFD
{
int fd;
struct stat st2;
@@ -148,7 +148,6 @@ check_directory(krb5_context context,
return EACCES;
}
}
-#endif
while((dent = readdir(d)) != NULL) {
if(strcmp(dent->d_name, ".") == 0 ||
@@ -166,6 +165,8 @@ check_directory(krb5_context context,
return ret;
}
+#endif /* !_WIN32 */
+
static krb5_boolean
match_local_principals(krb5_context context,
krb5_principal principal,
@@ -174,7 +175,7 @@ match_local_principals(krb5_context context,
krb5_error_code ret;
krb5_realm *realms, *r;
krb5_boolean result = FALSE;
-
+
/* multi-component principals can never match */
if(krb5_principal_get_comp_string(context, principal, 1) != NULL)
return FALSE;
@@ -182,7 +183,7 @@ match_local_principals(krb5_context context,
ret = krb5_get_default_realms (context, &realms);
if (ret)
return FALSE;
-
+
for (r = realms; *r != NULL; ++r) {
if(strcmp(krb5_principal_get_realm(context, principal),
*r) != 0)
@@ -198,17 +199,50 @@ match_local_principals(krb5_context context,
}
/**
- * Return TRUE iff `principal' is allowed to login as `luser'.
+ * This function takes the name of a local user and checks if
+ * principal is allowed to log in as that user.
+ *
+ * The user may have a ~/.k5login file listing principals that are
+ * allowed to login as that user. If that file does not exist, all
+ * principals with a first component identical to the username, and a
+ * realm considered local, are allowed access.
+ *
+ * The .k5login file must contain one principal per line, be owned by
+ * user and not be writable by group or other (but must be readable by
+ * anyone).
+ *
+ * Note that if the file exists, no implicit access rights are given
+ * to user@@LOCALREALM.
+ *
+ * Optionally, a set of files may be put in ~/.k5login.d (a
+ * directory), in which case they will all be checked in the same
+ * manner as .k5login. The files may be called anything, but files
+ * starting with a hash (#) , or ending with a tilde (~) are
+ * ignored. Subdirectories are not traversed. Note that this directory
+ * may not be checked by other Kerberos implementations.
+ *
+ * If no configuration file exists, match user against local domains,
+ * ie luser@@LOCAL-REALMS-IN-CONFIGURATION-FILES.
+ *
+ * @param context Kerberos 5 context.
+ * @param principal principal to check if allowed to login
+ * @param luser local user id
+ *
+ * @return returns TRUE if access should be granted, FALSE otherwise.
+ *
+ * @ingroup krb5_support
*/
-krb5_boolean KRB5_LIB_FUNCTION
+KRB5_LIB_FUNCTION krb5_boolean KRB5_LIB_CALL
krb5_kuserok (krb5_context context,
krb5_principal principal,
const char *luser)
{
+#ifndef _WIN32
char *buf;
size_t buflen;
- struct passwd *pwd;
+ struct passwd *pwd = NULL;
+ char *profile_dir = NULL;
krb5_error_code ret;
krb5_boolean result = FALSE;
@@ -225,14 +259,15 @@ krb5_kuserok (krb5_context context,
#endif
if (pwd == NULL)
return FALSE;
+ profile_dir = pwd->pw_dir;
#define KLOGIN "/.k5login"
- buflen = strlen(pwd->pw_dir) + sizeof(KLOGIN) + 2; /* 2 for .d */
+ buflen = strlen(profile_dir) + sizeof(KLOGIN) + 2; /* 2 for .d */
buf = malloc(buflen);
if(buf == NULL)
return FALSE;
/* check user's ~/.k5login */
- strlcpy(buf, pwd->pw_dir, buflen);
+ strlcpy(buf, profile_dir, buflen);
strlcat(buf, KLOGIN, buflen);
ret = check_one_file(context, buf, pwd, principal, &result);
@@ -241,7 +276,7 @@ krb5_kuserok (krb5_context context,
return TRUE;
}
- if(ret != ENOENT)
+ if(ret != ENOENT)
found_file = TRUE;
strlcat(buf, ".d", buflen);
@@ -250,7 +285,7 @@ krb5_kuserok (krb5_context context,
if(ret == 0 && result == TRUE)
return TRUE;
- if(ret != ENOENT && ret != ENOTDIR)
+ if(ret != ENOENT && ret != ENOTDIR)
found_file = TRUE;
/* finally if no files exist, allow all principals matching
@@ -259,4 +294,10 @@ krb5_kuserok (krb5_context context,
return match_local_principals(context, principal, luser);
return FALSE;
+#else
+ /* The .k5login file may be on a remote profile and we don't have
+ access to the profile until we have a token handle for the
+ user's credentials. */
+ return match_local_principals(context, principal, luser);
+#endif
}