kuserok + cache + /etc/k5login.d for users with /nonexistent passwd entries.
Harry Coin <[email protected]>
| Newsgroups | gmane.comp.encryption.kerberos.heimdal.general |
|---|---|
| Message-ID | <[email protected]> |
Here we add the ability for uname:uid combinations that have no home
directory to be matched against kerberos prinicpals in the manner of
.k5login.d, but we enable pattern matching in /etc/k5login.d (generally
adding the abilities seen in MIT), but also and we cache the results to
improve network traffic speeds. Here one administration place,
/etc/k5login.d serves to enhance both krb5_kuserok, and
krb5_aname_to_lname. Full sources here:
http://www.quietfountain.com/krb5nfspatches.tbz
Without these changes, principals having a / in the name will not be
able to use NFS, such users will regress to 'nobody:nogroup' .
RCSID("$Id: kuserok.c 16048 2005-09-09 10:33:33Z lha $");
/* see if principal is mentioned in the filename access file, return
TRUE (in result) if so, FALSE otherwise */
krb5_error_code
krb5_internal_check_one_file(krb5_context context,
const char *filename,
struct passwd *pwd,
krb5_const_principal principal,
int pattern_match_level,
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;
/* check type and mode of file */
if (fstat(fileno(f), &st) != 0) {
fclose (f);
return errno;
}
if (S_ISDIR(st.st_mode)) {
fclose (f);
return EISDIR;
}
if (st.st_uid != pwd->pw_uid && st.st_uid != 0) {
fclose (f);
return EACCES;
}
if ((st.st_mode & (S_IWGRP | S_IWOTH)) != 0) {
fclose (f);
return EACCES;
}
while (fgets (buf, sizeof(buf), f) != NULL) {
krb5_principal tmp;
char *newline = buf + strcspn(buf, "\n");
if(*newline != '\n') {
int c;
c = fgetc(f);
if(c != EOF) {
while(c != EOF && c != '\n')
c = fgetc(f);
/* line was too long, so ignore it */
continue;
}
}
*newline = '\0';
if (pattern_match_level>1) {
if (!strncmp(buf,"#STOP",5)) break;
}
ret = krb5_parse_name (context, buf, &tmp);
if (ret)
continue;
*result = (pattern_match_level ? krb5_principal_match (context,
principal, tmp): krb5_principal_compare (context, principal, tmp));
if (*result)
_krb5_luser_principal_add_to_cache(context,principal,pwd->pw_name);
krb5_free_principal (context, tmp);
if (*result) {
fclose (f);
return 0;
}
}
fclose (f);
return 0;
}
...
krb5_boolean KRB5_LIB_FUNCTION
krb5_kuserok (krb5_context context,
krb5_principal principal,
const char *luser)
{
char *buf;
size_t buflen;
struct passwd *pwd;
krb5_error_code ret;
krb5_boolean result = FALSE;
krb5_boolean found_file = FALSE;
#ifdef POSIX_GETPWNAM_R
char pwbuf[2048];
struct passwd pw;
if(getpwnam_r(luser, &pw, pwbuf, sizeof(pwbuf), &pwd) != 0)
return FALSE;
#else
pwd = getpwnam (luser);
#endif
if (pwd == NULL)
return FALSE;
if(0==_krb5_luser_principal_cache_query_luser(context,luser,&principal))
return TRUE;
buflen = strlen(luser) + strlen(ETCK5LOGIND) + 1;
buf = malloc(buflen);
if(buf == NULL)
return FALSE;
strlcpy(buf,ETCK5LOGIND,buflen);
strlcat(buf,luser,buflen);
ret = krb5_internal_check_one_file(context, buf, pwd, principal,
TRUE, &result);
free(buf);
if (ret == 0) return result; //if there is a file, don't process
further.
#define KLOGIN "/.k5login"
buflen = strlen(pwd->pw_dir) + sizeof(KLOGIN) + 2; /* 2 for .d */
,,,