Initial import from FreeBSD RELENG_4:
[games.git] / crypto / kerberosIV / lib / krb / kuserok.c
1 /*
2  * Copyright (c) 1995 - 1999 Kungliga Tekniska Högskolan
3  * (Royal Institute of Technology, Stockholm, Sweden).
4  * All rights reserved.
5  * 
6  * Redistribution and use in source and binary forms, with or without
7  * modification, are permitted provided that the following conditions
8  * are met:
9  * 
10  * 1. Redistributions of source code must retain the above copyright
11  *    notice, this list of conditions and the following disclaimer.
12  * 
13  * 2. Redistributions in binary form must reproduce the above copyright
14  *    notice, this list of conditions and the following disclaimer in the
15  *    documentation and/or other materials provided with the distribution.
16  * 
17  * 3. Neither the name of the Institute nor the names of its contributors
18  *    may be used to endorse or promote products derived from this software
19  *    without specific prior written permission.
20  * 
21  * THIS SOFTWARE IS PROVIDED BY THE INSTITUTE AND CONTRIBUTORS ``AS IS'' AND
22  * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
23  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
24  * ARE DISCLAIMED.  IN NO EVENT SHALL THE INSTITUTE OR CONTRIBUTORS BE LIABLE
25  * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
26  * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
27  * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
28  * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
29  * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
30  * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
31  * SUCH DAMAGE.
32  */
33
34 #include "krb_locl.h"
35
36 RCSID("$Id: kuserok.c,v 1.25 1999/12/02 16:58:42 joda Exp $");
37
38 #define OK 0
39 #define NOTOK 1
40 #define MAX_USERNAME 10
41
42 /*
43  * Return OK if `r' is one of the local realms, else NOTOK
44  */
45
46 static int
47 is_local_realm (const char *r)
48 {
49     char lrealm[REALM_SZ];
50     int n;
51
52     for (n = 1; krb_get_lrealm(lrealm, n) == KSUCCESS; ++n) {
53         if (strcmp (r, lrealm) == 0)
54             return OK;
55     }
56     return NOTOK;
57 }
58
59 /* 
60  * Given a Kerberos principal and a local username, determine whether
61  * user is authorized to login according to the authorization file
62  * ("~luser/.klogin" by default).  Returns OK if authorized, NOTOK if
63  * not authorized.
64  *
65  * IMPORTANT CHANGE: To eliminate the need of making a distinction
66  * between the 3 cases:
67  *
68  * 1. We can't verify that a .klogin file doesn't exist (no home dir).
69  * 2. It's there but we aren't allowed to read it.
70  * 3. We can read it and ~luser@LOCALREALM is (not) included.
71  *
72  * We instead make the assumption that luser@LOCALREALM is *always*
73  * included. Thus it is impossible to have an empty .klogin file and
74  * also to exclude luser@LOCALREALM from it. Root is treated differently
75  * since it's home should always be available.
76  *
77  * OLD STRATEGY:
78  * If there is no account for "luser" on the local machine, returns
79  * NOTOK.  If there is no authorization file, and the given Kerberos
80  * name "kdata" translates to the same name as "luser" (using
81  * krb_kntoln()), returns OK.  Otherwise, if the authorization file
82  * can't be accessed, returns NOTOK.  Otherwise, the file is read for
83  * a matching principal name, instance, and realm.  If one is found,
84  * returns OK, if none is found, returns NOTOK.
85  *
86  * The file entries are in the format:
87  *
88  *      name.instance@realm
89  *
90  * one entry per line.
91  *
92  */
93
94 int
95 krb_kuserok(char *name, char *instance, char *realm, char *luser)
96 {
97     struct passwd *pwd;
98     FILE *f;
99     char line[1024];
100     char file[MaxPathLen];
101     struct stat st;
102
103     pwd = getpwnam(luser);
104     if(pwd == NULL)
105         return NOTOK;
106     if (pwd->pw_uid != 0
107         && strcmp (name, luser) == 0
108         && strcmp (instance, "") == 0
109         && is_local_realm (realm) == OK)
110         return OK;
111
112     snprintf(file, sizeof(file), "%s/.klogin", pwd->pw_dir);
113
114     f = fopen(file, "r");
115     if(f == NULL)
116         return NOTOK;
117     
118     /* this is not a working test in filesystems like AFS and DFS */
119     if(fstat(fileno(f), &st) < 0){
120         fclose(f);
121         return NOTOK;
122     }
123     
124     if(st.st_uid != pwd->pw_uid){
125         fclose(f);
126         return NOTOK;
127     }
128     
129     while(fgets(line, sizeof(line), f)){
130         char fname[ANAME_SZ], finst[INST_SZ], frealm[REALM_SZ];
131         if(line[strlen(line) - 1] != '\n')
132             /* read till end of line */
133             while(1){
134                 int c = fgetc(f);
135                 if(c == '\n' || c == EOF)
136                     break;
137             }
138         else
139             line[strlen(line) - 1] = 0;
140         
141         if(kname_parse(fname, finst, frealm, line))
142             continue;
143         if(strcmp(name, fname))
144             continue;
145         if(strcmp(instance, finst))
146             continue;
147 #if 0 /* don't support principals without realm any longer */
148         if(frealm[0] == 0) {
149             if (is_local_realm (realm) != OK)
150                 continue;
151         } else
152 #endif
153         if (strcmp (realm, frealm))
154             continue;
155
156         fclose(f);
157         return OK;
158     }
159     fclose(f);
160     return NOTOK;
161 }
162
163 /* compatibility interface */
164
165 int
166 kuserok(AUTH_DAT *auth, char *luser)
167 {
168     return krb_kuserok(auth->pname, auth->pinst, auth->prealm, luser);
169 }