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 <afs/param.h>
11 #include <afsconfig.h>
16 #include <afs/pthread_glock.h>
17 #include <sys/types.h>
24 #include <netinet/in.h>
28 #include <stdlib.h> /* for realpath() */
36 #include <afs/afsutil.h>
37 #include <afs/fileutil.h>
39 #ifdef AFS_ATHENA_STDENV
44 #include "cellconfig.h"
46 #include "afs/audit.h"
48 afs_int32 afsconf_SuperUser();
51 int afsconf_CheckAuth(adir, acall)
52 register struct rx_call *acall;
53 register struct afsconf_dir *adir; {
55 return ((afsconf_SuperUser(adir, acall, (char *)0) == 0)? 10029 : 0);
58 #endif /* !defined(UKERNEL) */
60 static GetNoAuthFlag(adir)
61 struct afsconf_dir *adir; {
62 if (access(AFSDIR_SERVER_NOAUTH_FILEPATH, 0) == 0) {
63 osi_audit ( NoAuthEvent, 0, AUD_END ); /* some random server is running noauth */
64 return 1; /* if /usr/afs/local/NoAuth file exists, allow access */
70 afsconf_GetNoAuthFlag(adir)
71 struct afsconf_dir *adir; {
75 rc = GetNoAuthFlag(adir);
80 afsconf_SetNoAuthFlag(adir, aflag)
81 struct afsconf_dir *adir;
83 register afs_int32 code;
88 /* turn off noauth flag */
89 code = ( unlink(AFSDIR_SERVER_NOAUTH_FILEPATH) ? errno : 0 );
90 osi_audit ( NoAuthDisableEvent, code, AUD_END );
93 /* try to create file */
94 code = open(AFSDIR_SERVER_NOAUTH_FILEPATH, O_CREAT | O_TRUNC | O_RDWR, 0666);
97 osi_audit ( NoAuthEnableEvent, 0, AUD_END );
100 osi_audit ( NoAuthEnableEvent, errno, AUD_END );
105 /* deletes a user from the UserList file */
106 afsconf_DeleteUser(adir, auser)
107 struct afsconf_dir *adir;
108 register char *auser; {
118 register afs_int32 code;
121 strcompose(tbuffer, sizeof tbuffer, adir->name, "/", AFSDIR_ULIST_FILE, NULL);
125 * We attempt to fully resolve this pathname, so that the rename
126 * of the temporary file will work even if UserList is a symlink
127 * into a different filesystem.
129 char resolved_path[1024];
131 if (realpath(tbuffer, resolved_path)) {
132 strcpy(tbuffer, resolved_path);
135 #endif /* AFS_NT40_ENV */
136 tf = fopen(tbuffer, "r");
141 code = stat(tbuffer, &tstat);
146 strcpy(nbuffer, tbuffer);
147 strcat(nbuffer, ".NXX");
148 nf = fopen(nbuffer, "w+");
157 /* check for our user id */
158 tp = fgets(nbuffer, sizeof(nbuffer), tf);
159 if (tp == (char *)0) break;
160 code = sscanf(nbuffer, "%64s", tname);
161 if (code == 1 && strcmp(tname, auser) == 0) {
162 /* found the guy, don't copy to output file */
166 /* otherwise copy original line to output */
167 fprintf(nf, "%s", nbuffer);
171 if (ferror(nf)) flag = 1;
172 if (fclose(nf) == EOF) flag = 1;
173 strcpy(nbuffer, tbuffer);
174 strcat(nbuffer, ".NXX"); /* generate new file name again */
177 flag = renamefile(nbuffer, tbuffer);
179 flag = chmod(tbuffer, tstat.st_mode);
181 else unlink(nbuffer);
183 /* finally, decide what to return to the caller */
185 if (flag) return EIO; /* something mysterious went wrong */
186 if (!found) return ENOENT; /* entry wasn't found, no changes made */
187 return 0; /* everything was fine */
190 /* returns nth super user from the UserList file */
191 afsconf_GetNthUser(adir, an, abuffer, abufferLen)
192 struct afsconf_dir *adir;
195 afs_int32 abufferLen; {
201 register afs_int32 code;
204 strcompose(tbuffer, sizeof tbuffer, adir->name, "/", AFSDIR_ULIST_FILE, NULL);
205 tf = fopen(tbuffer, "r");
212 /* check for our user id */
213 tp = fgets(tbuffer, sizeof(tbuffer), tf);
214 if (tp == (char *)0) break;
215 code = sscanf(tbuffer, "%64s", tname);
216 if (code == 1 && an-- == 0) {
221 if (flag == 0) strcpy(abuffer, tname);
227 /* returns true iff user is in the UserList file */
228 static FindUser(adir, auser)
229 struct afsconf_dir *adir;
230 register char *auser; {
236 register afs_int32 code;
239 strcompose(tbuffer, sizeof tbuffer, adir->name, "/", AFSDIR_ULIST_FILE, NULL);
240 bp = BufioOpen(tbuffer, O_RDONLY, 0);
244 /* check for our user id */
245 rc = BufioGets(bp, tbuffer, sizeof(tbuffer));
247 code = sscanf(tbuffer, "%64s", tname);
248 if (code == 1 && strcmp(tname, auser) == 0) {
257 /* add a user to the user list, checking for duplicates */
258 afsconf_AddUser(adir, aname)
259 struct afsconf_dir *adir;
262 register afs_int32 code;
266 if (FindUser(adir, aname)) {
268 return EEXIST; /* already in the list */
271 strcompose(tbuffer, sizeof tbuffer, adir->name, "/", AFSDIR_ULIST_FILE, NULL);
272 tf = fopen(tbuffer, "a+");
277 fprintf(tf, "%s\n", aname);
279 if (ferror(tf)) code = EIO;
280 if (fclose(tf)) code = EIO;
285 /* special CompFindUser routine that builds up a princ and then
286 calls finduser on it. If found, returns char * to user string,
287 otherwise returns NULL. The resulting string should be immediately
288 copied to other storage prior to release of mutex. */
289 static char *CompFindUser(adir, name, sep, inst, realm)
290 struct afsconf_dir *adir;
296 static char fullname[ MAXKTCNAMELEN + MAXKTCNAMELEN +
297 MAXKTCREALMLEN + 3 ];
299 /* always must have name */
300 if ( !name || !name[0] ) { return NULL; }
301 strcpy(fullname, name);
303 /* might have instance */
304 if ( inst && inst[0] ) {
305 if ( !sep || !sep[0] ) { return NULL; }
307 strcat(fullname, sep);
308 strcat(fullname, inst);
311 /* might have realm */
312 if ( realm && realm[0] )
314 strcat(fullname, "@");
315 strcat(fullname, realm);
318 if ( FindUser(adir, fullname) ) {
326 /* make sure user authenticated on rx call acall is in list of valid
327 users. Copy the "real name" of the authenticated user into namep
328 if a pointer is passed.
330 afs_int32 afsconf_SuperUser(adir, acall, namep)
331 struct afsconf_dir *adir;
332 struct rx_call *acall;
334 register struct rx_connection *tconn;
335 register afs_int32 code;
344 if (afsconf_GetNoAuthFlag(adir)) {
345 if (namep) strcpy(namep, "<NoAuth>");
350 tconn = rx_ConnectionOf(acall);
351 code = rx_SecurityClassOf(tconn);
354 return 0; /* not authenticated at all, answer is no */
356 else if (code == 1) {
359 return 0; /* not supported any longer */
361 else if (code == 2) {
362 char tname[MAXKTCNAMELEN]; /* authentication from ticket */
363 char tinst[MAXKTCNAMELEN];
364 char tcell[MAXKTCREALMLEN];
365 char tcell_l[MAXKTCREALMLEN];
368 /* keep track of which one actually authorized request */
369 char uname[MAXKTCNAMELEN+MAXKTCNAMELEN+MAXKTCREALMLEN+3];
372 static char lcell[MAXCELLCHARS] = "";
373 static char lrealm[AFS_REALM_SZ] = "";
375 /* get auth details from server connection */
376 code = rxkad_GetServerInfo
377 (acall->conn, (afs_int32 *) 0, &exp,
378 tname, tinst, tcell, (afs_int32 *) 0);
381 return 0; /* bogus connection/other error */
384 /* don't bother checking anything else if tix have expired */
385 #ifdef AFS_PTHREAD_ENV
386 if (exp < clock_Sec()) {
388 if (exp < FT_ApproxTime()) {
391 return 0; /* expired tix */
394 /* generate lowercased version of cell name */
395 strcpy(tcell_l, tcell);
397 while ( *tmp ) { *tmp = tolower(*tmp); *tmp++; }
399 /* determine local cell name. It's static, so will only get
400 calculated the first time through */
402 afsconf_GetLocalCell(adir, lcell, sizeof(lcell));
404 /* if running a krb environment, also get the local realm */
405 /* note - this assumes AFS_REALM_SZ <= MAXCELLCHARS */
406 /* just set it to lcell if it fails */
408 if (afs_krb_get_lrealm(lrealm, 0) != 0) /* KSUCCESS */
409 strncpy(lrealm, lcell, AFS_REALM_SZ);
413 /* start with no uname and no authorization */
417 /* localauth special case */
418 if ( strlen(tinst) == 0 && strlen(tcell) == 0 &&
419 !strcmp(tname, AUTH_SUPERUSER) ) {
420 strcpy(uname, "<LocalAuth>");
423 /* cell of connection matches local cell or krb4 realm */
424 } else if ( !strcasecmp(tcell, lcell) || !strcasecmp(tcell,lrealm) ) {
425 if ( (tmp = CompFindUser(adir, tname, ".", tinst, NULL)) ) {
429 } else if ( (tmp = CompFindUser(adir, tname, "/", tinst, NULL)) ) {
435 /* cell of conn doesn't match local cell or realm */
437 if ( (tmp = CompFindUser(adir, tname, ".", tinst, tcell)) ) {
441 } else if ( (tmp = CompFindUser(adir, tname, "/", tinst, tcell)) ) {
445 } else if ( (tmp = CompFindUser(adir, tname, ".", tinst, tcell_l)) ) {
449 } else if ( (tmp = CompFindUser(adir, tname, "/", tinst, tcell_l)) ) {
457 strcpy(namep, uname);
461 else { /* some other auth type */
463 return 0; /* mysterious, just say no */