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
10 #include <afsconfig.h>
11 #include <afs/param.h>
17 #include <afs/pthread_glock.h>
18 #include <sys/types.h>
25 #include <netinet/in.h>
29 #include <stdlib.h> /* for realpath() */
37 #include <afs/afsutil.h>
38 #include <afs/fileutil.h>
40 #ifdef AFS_ATHENA_STDENV
45 #include "cellconfig.h"
47 #include "afs/audit.h"
49 afs_int32 afsconf_SuperUser();
53 afsconf_CheckAuth(adir, acall)
54 register struct rx_call *acall;
55 register struct afsconf_dir *adir;
57 LOCK_GLOBAL_MUTEX return ((afsconf_SuperUser(adir, acall, NULL) == 0) ?
60 #endif /* !defined(UKERNEL) */
64 struct afsconf_dir *adir;
66 if (access(AFSDIR_SERVER_NOAUTH_FILEPATH, 0) == 0) {
67 osi_audit(NoAuthEvent, 0, AUD_END); /* some random server is running noauth */
68 return 1; /* if /usr/afs/local/NoAuth file exists, allow access */
74 afsconf_GetNoAuthFlag(adir)
75 struct afsconf_dir *adir;
79 LOCK_GLOBAL_MUTEX rc = GetNoAuthFlag(adir);
80 UNLOCK_GLOBAL_MUTEX return rc;
83 afsconf_SetNoAuthFlag(adir, aflag)
84 struct afsconf_dir *adir;
87 register afs_int32 code;
89 LOCK_GLOBAL_MUTEX if (aflag == 0) {
90 /* turn off noauth flag */
91 code = (unlink(AFSDIR_SERVER_NOAUTH_FILEPATH) ? errno : 0);
92 osi_audit(NoAuthDisableEvent, code, AUD_END);
94 /* try to create file */
96 open(AFSDIR_SERVER_NOAUTH_FILEPATH, O_CREAT | O_TRUNC | O_RDWR,
100 osi_audit(NoAuthEnableEvent, 0, AUD_END);
102 osi_audit(NoAuthEnableEvent, errno, AUD_END);
106 /* deletes a user from the UserList file */
107 afsconf_DeleteUser(adir, auser)
108 struct afsconf_dir *adir;
109 register char *auser;
120 register afs_int32 code;
122 LOCK_GLOBAL_MUTEX strcompose(tbuffer, sizeof tbuffer, adir->name, "/",
123 AFSDIR_ULIST_FILE, NULL);
127 * We attempt to fully resolve this pathname, so that the rename
128 * of the temporary file will work even if UserList is a symlink
129 * into a different filesystem.
131 char resolved_path[1024];
133 if (realpath(tbuffer, resolved_path)) {
134 strcpy(tbuffer, resolved_path);
137 #endif /* AFS_NT40_ENV */
138 tf = fopen(tbuffer, "r");
140 UNLOCK_GLOBAL_MUTEX return -1;
142 code = stat(tbuffer, &tstat);
144 UNLOCK_GLOBAL_MUTEX return code;
146 strcpy(nbuffer, tbuffer);
147 strcat(nbuffer, ".NXX");
148 nf = fopen(nbuffer, "w+");
151 UNLOCK_GLOBAL_MUTEX return EIO;
156 /* check for our user id */
157 tp = fgets(nbuffer, sizeof(nbuffer), tf);
160 code = sscanf(nbuffer, "%64s", tname);
161 if (code == 1 && strcmp(tname, auser) == 0) {
162 /* found the guy, don't copy to output file */
165 /* otherwise copy original line to output */
166 fprintf(nf, "%s", nbuffer);
172 if (fclose(nf) == EOF)
174 strcpy(nbuffer, tbuffer);
175 strcat(nbuffer, ".NXX"); /* generate new file name again */
178 flag = renamefile(nbuffer, tbuffer);
180 flag = chmod(tbuffer, tstat.st_mode);
184 /* finally, decide what to return to the caller */
185 UNLOCK_GLOBAL_MUTEX if (flag)
186 return EIO; /* something mysterious went wrong */
188 return ENOENT; /* entry wasn't found, no changes made */
189 return 0; /* everything was fine */
192 /* returns nth super user from the UserList file */
193 afsconf_GetNthUser(adir, an, abuffer, abufferLen)
194 struct afsconf_dir *adir;
197 afs_int32 abufferLen;
204 register afs_int32 code;
206 LOCK_GLOBAL_MUTEX strcompose(tbuffer, sizeof tbuffer, adir->name, "/",
207 AFSDIR_ULIST_FILE, NULL);
208 tf = fopen(tbuffer, "r");
210 UNLOCK_GLOBAL_MUTEX return 1;
214 /* check for our user id */
215 tp = fgets(tbuffer, sizeof(tbuffer), tf);
218 code = sscanf(tbuffer, "%64s", tname);
219 if (code == 1 && an-- == 0) {
225 strcpy(abuffer, tname);
227 UNLOCK_GLOBAL_MUTEX return flag;
230 /* returns true iff user is in the UserList file */
232 FindUser(adir, auser)
233 struct afsconf_dir *adir;
234 register char *auser;
240 register afs_int32 code;
243 strcompose(tbuffer, sizeof tbuffer, adir->name, "/", AFSDIR_ULIST_FILE,
245 bp = BufioOpen(tbuffer, O_RDONLY, 0);
250 /* check for our user id */
251 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;
270 register afs_int32 code;
273 LOCK_GLOBAL_MUTEX if (FindUser(adir, aname)) {
274 UNLOCK_GLOBAL_MUTEX return EEXIST; /* already in the list */
277 strcompose(tbuffer, sizeof tbuffer, adir->name, "/", AFSDIR_ULIST_FILE,
279 tf = fopen(tbuffer, "a+");
281 UNLOCK_GLOBAL_MUTEX return EIO;
283 fprintf(tf, "%s\n", aname);
289 UNLOCK_GLOBAL_MUTEX return code;
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. */
297 CompFindUser(adir, name, sep, inst, realm)
298 struct afsconf_dir *adir;
304 static char fullname[MAXKTCNAMELEN + MAXKTCNAMELEN + MAXKTCREALMLEN + 3];
306 /* always must have name */
307 if (!name || !name[0]) {
310 strcpy(fullname, name);
312 /* might have instance */
313 if (inst && inst[0]) {
314 if (!sep || !sep[0]) {
318 strcat(fullname, sep);
319 strcat(fullname, inst);
322 /* might have realm */
323 if (realm && realm[0]) {
324 strcat(fullname, "@");
325 strcat(fullname, realm);
328 if (FindUser(adir, fullname)) {
336 /* make sure user authenticated on rx call acall is in list of valid
337 users. Copy the "real name" of the authenticated user into namep
338 if a pointer is passed.
341 afsconf_SuperUser(adir, acall, namep)
342 struct afsconf_dir *adir;
343 struct rx_call *acall;
346 register struct rx_connection *tconn;
347 register afs_int32 code;
350 LOCK_GLOBAL_MUTEX if (!adir) {
351 UNLOCK_GLOBAL_MUTEX return 0;
354 if (afsconf_GetNoAuthFlag(adir)) {
356 strcpy(namep, "<NoAuth>");
357 UNLOCK_GLOBAL_MUTEX return 1;
360 tconn = rx_ConnectionOf(acall);
361 code = rx_SecurityClassOf(tconn);
363 UNLOCK_GLOBAL_MUTEX return 0; /* not authenticated at all, answer is no */
364 } else if (code == 1) {
366 UNLOCK_GLOBAL_MUTEX return 0; /* not supported any longer */
367 } else if (code == 2) {
368 char tname[MAXKTCNAMELEN]; /* authentication from ticket */
369 char tinst[MAXKTCNAMELEN];
370 char tcell[MAXKTCREALMLEN];
371 char tcell_l[MAXKTCREALMLEN];
374 /* keep track of which one actually authorized request */
375 char uname[MAXKTCNAMELEN + MAXKTCNAMELEN + MAXKTCREALMLEN + 3];
378 static char lcell[MAXCELLCHARS] = "";
379 static char lrealm[AFS_REALM_SZ] = "";
381 /* get auth details from server connection */
383 rxkad_GetServerInfo(acall->conn, NULL, &exp, tname, tinst, tcell,
386 UNLOCK_GLOBAL_MUTEX return 0; /* bogus connection/other error */
389 /* don't bother checking anything else if tix have expired */
390 #ifdef AFS_PTHREAD_ENV
391 if (exp < clock_Sec()) {
393 if (exp < FT_ApproxTime()) {
395 UNLOCK_GLOBAL_MUTEX return 0; /* expired tix */
398 /* generate lowercased version of cell name */
399 strcpy(tcell_l, tcell);
402 *tmp = tolower(*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);
465 UNLOCK_GLOBAL_MUTEX return flag;
466 } else { /* some other auth type */
467 UNLOCK_GLOBAL_MUTEX return 0; /* mysterious, just say no */