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;
58 return ((afsconf_SuperUser(adir, acall, NULL) == 0) ? 10029 : 0);
61 #endif /* !defined(UKERNEL) */
65 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 */
76 afsconf_GetNoAuthFlag(adir)
77 struct afsconf_dir *adir;
82 rc = GetNoAuthFlag(adir);
88 afsconf_SetNoAuthFlag(adir, aflag)
89 struct afsconf_dir *adir;
92 register afs_int32 code;
96 /* turn off noauth flag */
97 code = (unlink(AFSDIR_SERVER_NOAUTH_FILEPATH) ? errno : 0);
98 osi_audit(NoAuthDisableEvent, code, AUD_END);
100 /* try to create file */
102 open(AFSDIR_SERVER_NOAUTH_FILEPATH, O_CREAT | O_TRUNC | O_RDWR,
106 osi_audit(NoAuthEnableEvent, 0, AUD_END);
108 osi_audit(NoAuthEnableEvent, errno, AUD_END);
113 /* deletes a user from the UserList file */
115 afsconf_DeleteUser(adir, auser)
116 struct afsconf_dir *adir;
117 register char *auser;
128 register afs_int32 code;
131 strcompose(tbuffer, sizeof tbuffer, adir->name, "/",
132 AFSDIR_ULIST_FILE, NULL);
136 * We attempt to fully resolve this pathname, so that the rename
137 * of the temporary file will work even if UserList is a symlink
138 * into a different filesystem.
140 char resolved_path[1024];
142 if (realpath(tbuffer, resolved_path)) {
143 strcpy(tbuffer, resolved_path);
146 #endif /* AFS_NT40_ENV */
147 tf = fopen(tbuffer, "r");
152 code = stat(tbuffer, &tstat);
157 strcpy(nbuffer, tbuffer);
158 strcat(nbuffer, ".NXX");
159 nf = fopen(nbuffer, "w+");
168 /* check for our user id */
169 tp = fgets(nbuffer, sizeof(nbuffer), tf);
172 code = sscanf(nbuffer, "%64s", tname);
173 if (code == 1 && strcmp(tname, auser) == 0) {
174 /* found the guy, don't copy to output file */
177 /* otherwise copy original line to output */
178 fprintf(nf, "%s", nbuffer);
184 if (fclose(nf) == EOF)
186 strcpy(nbuffer, tbuffer);
187 strcat(nbuffer, ".NXX"); /* generate new file name again */
190 flag = renamefile(nbuffer, tbuffer);
192 flag = chmod(tbuffer, tstat.st_mode);
196 /* finally, decide what to return to the caller */
199 return EIO; /* something mysterious went wrong */
201 return ENOENT; /* entry wasn't found, no changes made */
202 return 0; /* everything was fine */
205 /* returns nth super user from the UserList file */
207 afsconf_GetNthUser(adir, an, abuffer, abufferLen)
208 struct afsconf_dir *adir;
211 afs_int32 abufferLen;
218 register afs_int32 code;
221 strcompose(tbuffer, sizeof tbuffer, adir->name, "/",
222 AFSDIR_ULIST_FILE, NULL);
223 tf = fopen(tbuffer, "r");
230 /* check for our user id */
231 tp = fgets(tbuffer, sizeof(tbuffer), tf);
234 code = sscanf(tbuffer, "%64s", tname);
235 if (code == 1 && an-- == 0) {
241 strcpy(abuffer, tname);
247 /* returns true iff user is in the UserList file */
249 FindUser(adir, auser)
250 struct afsconf_dir *adir;
251 register char *auser;
257 register afs_int32 code;
260 strcompose(tbuffer, sizeof tbuffer, adir->name, "/", AFSDIR_ULIST_FILE,
262 bp = BufioOpen(tbuffer, O_RDONLY, 0);
267 /* check for our user id */
268 rc = BufioGets(bp, tbuffer, sizeof(tbuffer));
271 code = sscanf(tbuffer, "%64s", tname);
272 if (code == 1 && strcmp(tname, auser) == 0) {
281 /* add a user to the user list, checking for duplicates */
283 afsconf_AddUser(adir, aname)
284 struct afsconf_dir *adir;
288 register afs_int32 code;
292 if (FindUser(adir, aname)) {
294 return EEXIST; /* already in the list */
297 strcompose(tbuffer, sizeof tbuffer, adir->name, "/", AFSDIR_ULIST_FILE,
299 tf = fopen(tbuffer, "a+");
304 fprintf(tf, "%s\n", aname);
314 /* special CompFindUser routine that builds up a princ and then
315 calls finduser on it. If found, returns char * to user string,
316 otherwise returns NULL. The resulting string should be immediately
317 copied to other storage prior to release of mutex. */
319 CompFindUser(adir, name, sep, inst, realm)
320 struct afsconf_dir *adir;
326 static char fullname[MAXKTCNAMELEN + MAXKTCNAMELEN + MAXKTCREALMLEN + 3];
328 /* always must have name */
329 if (!name || !name[0]) {
332 strcpy(fullname, name);
334 /* might have instance */
335 if (inst && inst[0]) {
336 if (!sep || !sep[0]) {
340 strcat(fullname, sep);
341 strcat(fullname, inst);
344 /* might have realm */
345 if (realm && realm[0]) {
346 strcat(fullname, "@");
347 strcat(fullname, realm);
350 if (FindUser(adir, fullname)) {
358 /* make sure user authenticated on rx call acall is in list of valid
359 users. Copy the "real name" of the authenticated user into namep
360 if a pointer is passed.
363 afsconf_SuperUser(adir, acall, namep)
364 struct afsconf_dir *adir;
365 struct rx_call *acall;
368 register struct rx_connection *tconn;
369 register afs_int32 code;
378 if (afsconf_GetNoAuthFlag(adir)) {
380 strcpy(namep, "<NoAuth>");
385 tconn = rx_ConnectionOf(acall);
386 code = rx_SecurityClassOf(tconn);
389 return 0; /* not authenticated at all, answer is no */
390 } else if (code == 1) {
393 return 0; /* not supported any longer */
394 } else if (code == 2) {
395 char tname[MAXKTCNAMELEN]; /* authentication from ticket */
396 char tinst[MAXKTCNAMELEN];
397 char tcell[MAXKTCREALMLEN];
398 char tcell_l[MAXKTCREALMLEN];
401 /* keep track of which one actually authorized request */
402 char uname[MAXKTCNAMELEN + MAXKTCNAMELEN + MAXKTCREALMLEN + 3];
405 static char lcell[MAXCELLCHARS] = "";
406 static char lrealms[AFS_NUM_LREALMS][AFS_REALM_SZ];
407 static int num_lrealms = -1;
408 int lrealm_match = 0, i;
410 /* get auth details from server connection */
412 rxkad_GetServerInfo(acall->conn, NULL, &exp, tname, tinst, tcell,
416 return 0; /* bogus connection/other error */
419 /* don't bother checking anything else if tix have expired */
420 #ifdef AFS_PTHREAD_ENV
421 if (exp < clock_Sec()) {
423 if (exp < FT_ApproxTime()) {
426 return 0; /* expired tix */
429 /* generate lowercased version of cell name */
430 strcpy(tcell_l, tcell);
433 *tmp = tolower(*tmp);
437 /* determine local cell name. It's static, so will only get
438 * calculated the first time through */
440 afsconf_GetLocalCell(adir, lcell, sizeof(lcell));
442 /* if running a krb environment, also get the local realm */
443 /* note - this assumes AFS_REALM_SZ <= MAXCELLCHARS */
444 /* just set it to lcell if it fails */
445 if (num_lrealms == -1) {
446 for (i=0; i<AFS_NUM_LREALMS; i++) {
447 if (afs_krb_get_lrealm(lrealms[i], i) != 0 /*KSUCCESS*/)
452 strncpy(lrealms[0], lcell, AFS_REALM_SZ);
459 /* See if the ticket cell matches one of the local realms */
461 for ( i=0;i<num_lrealms;i++ ) {
462 if (!strcasecmp(lrealms[i], tcell)) {
468 /* If yes, then make sure that the name is not present in
469 * an exclusion list */
472 snprintf(uname,sizeof(uname),"%s.%s@%s",tname,tinst,tcell);
474 snprintf(uname,sizeof(uname),"%s@%s",tname,tcell);
476 if (afs_krb_exclusion(uname))
480 /* start with no uname and no authorization */
484 /* localauth special case */
485 if (strlen(tinst) == 0 && strlen(tcell) == 0
486 && !strcmp(tname, AUTH_SUPERUSER)) {
487 strcpy(uname, "<LocalAuth>");
490 /* cell of connection matches local cell or one of the realms */
491 } else if (!strcasecmp(tcell, lcell) || lrealm_match) {
492 if ((tmp = CompFindUser(adir, tname, ".", tinst, NULL))) {
496 } else if ((tmp = CompFindUser(adir, tname, "/", tinst, NULL))) {
501 /* cell of conn doesn't match local cell or realm */
503 if ((tmp = CompFindUser(adir, tname, ".", tinst, tcell))) {
507 } else if ((tmp = CompFindUser(adir, tname, "/", tinst, tcell))) {
511 } else if ((tmp = CompFindUser(adir, tname, ".", tinst, tcell_l))) {
515 } else if ((tmp = CompFindUser(adir, tname, "/", tinst, tcell_l))) {
523 strcpy(namep, uname);
526 } else { /* some other auth type */
528 return 0; /* mysterious, just say no */