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 */
,,,
lmpx.com only provides a reader for public news (NNTP) servers. It is not affiliated with the servers or forums shown here and is not responsible for the content of articles, which is written by their respective authors.