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() */
44 #include <afs/afsutil.h>
45 #include <afs/fileutil.h>
47 #ifdef AFS_ATHENA_STDENV
52 #include "cellconfig.h"
54 #include "afs/audit.h"
58 int afsconf_CheckAuth(adir, acall)
59 register struct rx_call *acall;
60 register struct afsconf_dir *adir; {
62 return ((afsconf_SuperUser(adir, acall, (char *)0) == 0)? 10029 : 0);
65 #endif /* !defined(UKERNEL) */
67 static GetNoAuthFlag(adir)
68 struct afsconf_dir *adir; {
69 if (access(AFSDIR_SERVER_NOAUTH_FILEPATH, 0) == 0) {
70 osi_audit ( NoAuthEvent, 0, AUD_END ); /* some random server is running noauth */
71 return 1; /* if /usr/afs/local/NoAuth file exists, allow access */
77 afsconf_GetNoAuthFlag(adir)
78 struct afsconf_dir *adir; {
82 rc = GetNoAuthFlag(adir);
87 afsconf_SetNoAuthFlag(adir, aflag)
88 struct afsconf_dir *adir;
90 register afs_int32 code;
95 /* turn off noauth flag */
96 code = ( unlink(AFSDIR_SERVER_NOAUTH_FILEPATH) ? errno : 0 );
97 osi_audit ( NoAuthDisableEvent, code, AUD_END );
100 /* try to create file */
101 code = open(AFSDIR_SERVER_NOAUTH_FILEPATH, O_CREAT | O_TRUNC | O_RDWR, 0666);
104 osi_audit ( NoAuthEnableEvent, 0, AUD_END );
107 osi_audit ( NoAuthEnableEvent, errno, AUD_END );
112 /* deletes a user from the UserList file */
113 afsconf_DeleteUser(adir, auser)
114 struct afsconf_dir *adir;
115 register char *auser; {
125 register afs_int32 code;
128 strcompose(tbuffer, sizeof tbuffer, adir->name, "/", AFSDIR_ULIST_FILE, NULL);
132 * We attempt to fully resolve this pathname, so that the rename
133 * of the temporary file will work even if UserList is a symlink
134 * into a different filesystem.
136 char resolved_path[1024];
138 if (realpath(tbuffer, resolved_path)) {
139 strcpy(tbuffer, resolved_path);
142 #endif /* AFS_NT40_ENV */
143 tf = fopen(tbuffer, "r");
148 code = stat(tbuffer, &tstat);
153 strcpy(nbuffer, tbuffer);
154 strcat(nbuffer, ".NXX");
155 nf = fopen(nbuffer, "w+");
164 /* check for our user id */
165 tp = fgets(nbuffer, sizeof(nbuffer), tf);
166 if (tp == (char *)0) break;
167 code = sscanf(nbuffer, "%64s", tname);
168 if (code == 1 && strcmp(tname, auser) == 0) {
169 /* found the guy, don't copy to output file */
173 /* otherwise copy original line to output */
174 fprintf(nf, "%s", nbuffer);
178 if (ferror(nf)) flag = 1;
179 if (fclose(nf) == EOF) flag = 1;
180 strcpy(nbuffer, tbuffer);
181 strcat(nbuffer, ".NXX"); /* generate new file name again */
184 flag = renamefile(nbuffer, tbuffer);
186 flag = chmod(tbuffer, tstat.st_mode);
188 else unlink(nbuffer);
190 /* finally, decide what to return to the caller */
192 if (flag) return EIO; /* something mysterious went wrong */
193 if (!found) return ENOENT; /* entry wasn't found, no changes made */
194 return 0; /* everything was fine */
197 /* returns nth super user from the UserList file */
198 afsconf_GetNthUser(adir, an, abuffer, abufferLen)
199 struct afsconf_dir *adir;
202 afs_int32 abufferLen; {
208 register afs_int32 code;
211 strcompose(tbuffer, sizeof tbuffer, adir->name, "/", AFSDIR_ULIST_FILE, NULL);
212 tf = fopen(tbuffer, "r");
219 /* check for our user id */
220 tp = fgets(tbuffer, sizeof(tbuffer), tf);
221 if (tp == (char *)0) break;
222 code = sscanf(tbuffer, "%64s", tname);
223 if (code == 1 && an-- == 0) {
228 if (flag == 0) strcpy(abuffer, tname);
234 /* returns true iff user is in the UserList file */
235 static FindUser(adir, auser)
236 struct afsconf_dir *adir;
237 register char *auser; {
243 register afs_int32 code;
246 strcompose(tbuffer, sizeof tbuffer, adir->name, "/", AFSDIR_ULIST_FILE, NULL);
247 bp = BufioOpen(tbuffer, O_RDONLY, 0);
251 /* check for our user id */
252 rc = BufioGets(bp, tbuffer, sizeof(tbuffer));
254 code = sscanf(tbuffer, "%64s", tname);
255 if (code == 1 && strcmp(tname, auser) == 0) {
264 /* add a user to the user list, checking for duplicates */
265 afsconf_AddUser(adir, aname)
266 struct afsconf_dir *adir;
269 register afs_int32 code;
273 if (FindUser(adir, aname)) {
275 return EEXIST; /* already in the list */
278 strcompose(tbuffer, sizeof tbuffer, adir->name, "/", AFSDIR_ULIST_FILE, NULL);
279 tf = fopen(tbuffer, "a+");
284 fprintf(tf, "%s\n", aname);
286 if (ferror(tf)) code = EIO;
287 if (fclose(tf)) code = EIO;
292 /* special CompFindUser routine that builds up a princ and then
293 calls finduser on it. If found, returns char * to user string,
294 otherwise returns NULL. The resulting string should be immediately
295 copied to other storage prior to release of mutex. */
296 static char *CompFindUser(adir, name, sep, inst, realm)
297 struct afsconf_dir *adir;
303 static char fullname[ MAXKTCNAMELEN + MAXKTCNAMELEN +
304 MAXKTCREALMLEN + 3 ];
306 /* always must have name */
307 if ( !name || !name[0] ) { return NULL; }
308 strcpy(fullname, name);
310 /* might have instance */
311 if ( inst && inst[0] ) {
312 if ( !sep || !sep[0] ) { return NULL; }
314 strcat(fullname, sep);
315 strcat(fullname, inst);
318 /* might have realm */
319 if ( realm && realm[0] )
321 strcat(fullname, "@");
322 strcat(fullname, realm);
325 if ( FindUser(adir, fullname) ) {
333 /* make sure user authenticated on rx call acall is in list of valid
334 users. Copy the "real name" of the authenticated user into namep
335 if a pointer is passed.
337 afs_int32 afsconf_SuperUser(adir, acall, namep)
338 struct afsconf_dir *adir;
339 struct rx_call *acall;
341 register struct rx_connection *tconn;
342 register afs_int32 code;
351 if (afsconf_GetNoAuthFlag(adir)) {
352 if (namep) strcpy(namep, "<NoAuth>");
357 tconn = rx_ConnectionOf(acall);
358 code = rx_SecurityClassOf(tconn);
361 return 0; /* not authenticated at all, answer is no */
363 else if (code == 1) {
366 return 0; /* not supported any longer */
368 else if (code == 2) {
369 char tname[MAXKTCNAMELEN]; /* authentication from ticket */
370 char tinst[MAXKTCNAMELEN];
371 char tcell[MAXKTCREALMLEN];
372 char tcell_l[MAXKTCREALMLEN];
375 /* keep track of which one actually authorized request */
376 char uname[MAXKTCNAMELEN+MAXKTCNAMELEN+MAXKTCREALMLEN+3];
379 static char lcell[MAXCELLCHARS] = "";
380 static char lrealm[AFS_REALM_SZ] = "";
382 /* get auth details from server connection */
383 code = rxkad_GetServerInfo
384 (acall->conn, (afs_int32 *) 0, &exp,
385 tname, tinst, tcell, (afs_int32 *) 0);
388 return 0; /* bogus connection/other error */
391 /* don't bother checking anything else if tix have expired */
392 #ifdef AFS_PTHREAD_ENV
393 if (exp < clock_Sec()) {
395 if (exp < FT_ApproxTime()) {
398 return 0; /* expired tix */
401 /* generate lowercased version of cell name */
402 strcpy(tcell_l, tcell);
404 while ( *tmp ) { *tmp = tolower(*tmp); *tmp++; }
406 /* determine local cell name. It's static, so will only get
407 calculated the first time through */
409 afsconf_GetLocalCell(adir, lcell, sizeof(lcell));
411 /* if running a krb environment, also get the local realm */
412 /* note - this assumes AFS_REALM_SZ <= MAXCELLCHARS */
413 /* just set it to lcell if it fails */
415 if (afs_krb_get_lrealm(lrealm, 0) != 0) /* KSUCCESS */
416 strncpy(lrealm, lcell, AFS_REALM_SZ);
420 /* start with no uname and no authorization */
424 /* localauth special case */
425 if ( strlen(tinst) == 0 && strlen(tcell) == 0 &&
426 !strcmp(tname, AUTH_SUPERUSER) ) {
427 strcpy(uname, "<LocalAuth>");
430 /* cell of connection matches local cell or krb4 realm */
431 } else if ( !strcasecmp(tcell, lcell) || !strcasecmp(tcell,lrealm) ) {
432 if ( (tmp = CompFindUser(adir, tname, ".", tinst, NULL)) ) {
436 } else if ( (tmp = CompFindUser(adir, tname, "/", tinst, NULL)) ) {
442 /* cell of conn doesn't match local cell or realm */
444 if ( (tmp = CompFindUser(adir, tname, ".", tinst, tcell)) ) {
448 } else if ( (tmp = CompFindUser(adir, tname, "/", tinst, tcell)) ) {
452 } else if ( (tmp = CompFindUser(adir, tname, ".", tinst, tcell_l)) ) {
456 } else if ( (tmp = CompFindUser(adir, tname, "/", tinst, tcell_l)) ) {
464 strcpy(namep, uname);
468 else { /* some other auth type */
470 return 0; /* mysterious, just say no */