2 * Copyright 2000, International Business Machines Corporation and others.
5 * This software has been released under the terms of the IBM Public
6 * License. For details, see the LICENSE file in the top-level source
7 * directory or online at http://www.openafs.org/dl/license10.html
11 * Revision 2.3 91/08/09 18:10:56
12 * added a new param to afsconf_SuperUser
14 * Revision 2.2 90/08/29 15:10:43
16 * Reject security index #1: rxvab/bcrypt.
18 * Revision 2.1 90/08/07 18:52:21
19 * Start with clean version to sync test and dev trees.
22 #include <afs/param.h>
24 #include <afs/pthread_glock.h>
25 #include <sys/types.h>
32 #include <netinet/in.h>
36 #include <stdlib.h> /* for realpath() */
42 #include <afs/afsutil.h>
43 #include <afs/fileutil.h>
45 #ifdef AFS_ATHENA_STDENV
50 #include "cellconfig.h"
52 #include "afs/audit.h"
56 int afsconf_CheckAuth(adir, acall)
57 register struct rx_call *acall;
58 register struct afsconf_dir *adir; {
60 return ((afsconf_SuperUser(adir, acall, (char *)0) == 0)? 10029 : 0);
63 #endif /* !defined(UKERNEL) */
65 static GetNoAuthFlag(adir)
66 struct afsconf_dir *adir; {
67 if (access(AFSDIR_SERVER_NOAUTH_FILEPATH, 0) == 0) {
68 osi_audit ( NoAuthEvent, 0, AUD_END ); /* some random server is running noauth */
69 return 1; /* if /usr/afs/local/NoAuth file exists, allow access */
75 afsconf_GetNoAuthFlag(adir)
76 struct afsconf_dir *adir; {
80 rc = GetNoAuthFlag(adir);
85 afsconf_SetNoAuthFlag(adir, aflag)
86 struct afsconf_dir *adir;
88 register afs_int32 code;
93 /* turn off noauth flag */
94 code = ( unlink(AFSDIR_SERVER_NOAUTH_FILEPATH) ? errno : 0 );
95 osi_audit ( NoAuthDisableEvent, code, AUD_END );
98 /* try to create file */
99 code = open(AFSDIR_SERVER_NOAUTH_FILEPATH, O_CREAT | O_TRUNC | O_RDWR, 0666);
102 osi_audit ( NoAuthEnableEvent, 0, AUD_END );
105 osi_audit ( NoAuthEnableEvent, errno, AUD_END );
110 /* deletes a user from the UserList file */
111 afsconf_DeleteUser(adir, auser)
112 struct afsconf_dir *adir;
113 register char *auser; {
123 register afs_int32 code;
126 strcompose(tbuffer, sizeof tbuffer, adir->name, "/", AFSDIR_ULIST_FILE, NULL);
130 * We attempt to fully resolve this pathname, so that the rename
131 * of the temporary file will work even if UserList is a symlink
132 * into a different filesystem.
134 char resolved_path[1024];
136 if (realpath(tbuffer, resolved_path)) {
137 strcpy(tbuffer, resolved_path);
140 #endif /* AFS_NT40_ENV */
141 tf = fopen(tbuffer, "r");
146 code = stat(tbuffer, &tstat);
151 strcpy(nbuffer, tbuffer);
152 strcat(nbuffer, ".NXX");
153 nf = fopen(nbuffer, "w+");
162 /* check for our user id */
163 tp = fgets(nbuffer, sizeof(nbuffer), tf);
164 if (tp == (char *)0) break;
165 code = sscanf(nbuffer, "%64s", tname);
166 if (code == 1 && strcmp(tname, auser) == 0) {
167 /* found the guy, don't copy to output file */
171 /* otherwise copy original line to output */
172 fprintf(nf, "%s", nbuffer);
176 if (ferror(nf)) flag = 1;
177 if (fclose(nf) == EOF) flag = 1;
178 strcpy(nbuffer, tbuffer);
179 strcat(nbuffer, ".NXX"); /* generate new file name again */
182 flag = renamefile(nbuffer, tbuffer);
184 flag = chmod(tbuffer, tstat.st_mode);
186 else unlink(nbuffer);
188 /* finally, decide what to return to the caller */
190 if (flag) return EIO; /* something mysterious went wrong */
191 if (!found) return ENOENT; /* entry wasn't found, no changes made */
192 return 0; /* everything was fine */
195 /* returns nth super user from the UserList file */
196 afsconf_GetNthUser(adir, an, abuffer, abufferLen)
197 struct afsconf_dir *adir;
200 afs_int32 abufferLen; {
206 register afs_int32 code;
209 strcompose(tbuffer, sizeof tbuffer, adir->name, "/", AFSDIR_ULIST_FILE, NULL);
210 tf = fopen(tbuffer, "r");
217 /* check for our user id */
218 tp = fgets(tbuffer, sizeof(tbuffer), tf);
219 if (tp == (char *)0) break;
220 code = sscanf(tbuffer, "%64s", tname);
221 if (code == 1 && an-- == 0) {
226 if (flag == 0) strcpy(abuffer, tname);
232 /* returns true iff user is in the UserList file */
233 static FindUser(adir, auser)
234 struct afsconf_dir *adir;
235 register char *auser; {
241 register afs_int32 code;
244 strcompose(tbuffer, sizeof tbuffer, adir->name, "/", AFSDIR_ULIST_FILE, NULL);
245 bp = BufioOpen(tbuffer, O_RDONLY, 0);
249 /* check for our user id */
250 rc = BufioGets(bp, tbuffer, sizeof(tbuffer));
252 code = sscanf(tbuffer, "%64s", tname);
253 if (code == 1 && strcmp(tname, auser) == 0) {
262 /* add a user to the user list, checking for duplicates */
263 afsconf_AddUser(adir, aname)
264 struct afsconf_dir *adir;
267 register afs_int32 code;
271 if (FindUser(adir, aname)) {
273 return EEXIST; /* already in the list */
276 strcompose(tbuffer, sizeof tbuffer, adir->name, "/", AFSDIR_ULIST_FILE, NULL);
277 tf = fopen(tbuffer, "a+");
282 fprintf(tf, "%s\n", aname);
284 if (ferror(tf)) code = EIO;
285 if (fclose(tf)) code = EIO;
290 /* make sure user authenticated on rx call acall is in list of valid
293 afsconf_SuperUser(adir, acall, namep)
294 struct afsconf_dir *adir;
295 struct rx_call *acall;
297 register struct rx_connection *tconn;
298 register afs_int32 code;
306 if (afsconf_GetNoAuthFlag(adir)) {
307 if (namep) strcpy(namep, "<noauth>");
311 tconn = rx_ConnectionOf(acall);
312 code = rx_SecurityClassOf(tconn);
315 return 0; /* not authenticated at all, answer is no */
317 else if (code == 1) {
320 return 0; /* not supported any longer */
322 else if (code == 2) {
323 char tname[MAXKTCNAMELEN]; /* authentication from ticket */
324 char tinst[MAXKTCNAMELEN];
325 char tcell[MAXKTCREALMLEN];
326 char uname[MAXKTCNAMELEN]; /* name.instance */
327 int ilen; /* length of instance */
329 static char localcellname[MAXCELLCHARS] = "";
330 #if defined(AFS_ATHENA_STDENV) || defined(AFS_KERBREALM_ENV)
331 static char local_realm[AFS_REALM_SZ] = "";
335 code = rxkad_GetServerInfo
336 (acall->conn, (afs_int32 *) 0, &exp, tname, tinst, tcell, (afs_int32 *) 0);
339 return 0; /* bogus */
342 if (strlen (tcell)) {
343 if (!localcellname[0])
345 (adir, localcellname, sizeof(localcellname));
346 #if defined(AFS_ATHENA_STDENV) || defined(AFS_KERBREALM_ENV)
347 if (!local_realm[0]) {
348 if (afs_krb_get_lrealm(local_realm, 0) != 0/*KSUCCESS*/)
349 strncpy(local_realm, localcellname, AFS_REALM_SZ);
351 if (strcasecmp(local_realm, tcell) &&
352 (strcasecmp(localcellname, tcell)))
354 if (strcasecmp(localcellname, tcell))
361 ilen = strlen(tinst);
362 strncpy (uname, tname, sizeof(uname));
364 if (strlen(uname) + 1 + ilen >= sizeof(uname)) {
369 strcat (uname, tinst);
372 #ifdef AFS_PTHREAD_ENV
373 if (exp < clock_Sec()) {
375 if (exp < FT_ApproxTime()) {
378 return 0; /* expired tix */
380 if (strcmp(AUTH_SUPERUSER, uname) == 0) flag = 1;
381 else flag = FindUser(adir, uname); /* true iff in userlist file */
383 strcpy(namep, uname);
389 return 0; /* mysterious, just say no */