[OpenAFS-devel] Rewite of the auth/userok.c SuperUser check routine
Nathan Neulinger
nneul@umr.edu
Fri, 11 May 2001 10:08:42 -0500
--gKMricLos+KVdGMg
Content-Type: text/plain; charset=us-ascii
Content-Disposition: inline
This rewrite cleans up the code a bit, removes any athena specific
references (not needed anymore in this version), and adds support for
multi realm management of afs servers (you can now specify
"admin@OTHERREALM" in your userlist).
Code now checks as follows:
tname
tinst - remote user info from conn
tcell
lcell - local cell
lrealm - local realm (defaults to lcell if not avail)
if no remote cell or instance
allow localauth
if the cell of the remote connection matches local cell or local realm
if not tinst
allow if tname in UserList
if tinst
allow if tname.tinst in UserList
allow if tname/tinst in UserList
if cell doesn't match local cell or realm
if not tinst
allow if tname@cell in UserList
allow if tname@CELL in UserList
if tinst
allow if tname.tinst@cell in UserList
allow if tname/tinst@cell in UserList
allow if tname.tinst@CELL in UserList
allow if tname/tinst@CELL in UserList
note - it may not actually be "CELL". It basically checks for the
tolower()'d version of the cell name. This way, you can either use the
same style as in pts (user@realm) or the typical krb5 style (user@REALM).
-- Nathan
------------------------------------------------------------
Nathan Neulinger EMail: nneul@umr.edu
University of Missouri - Rolla Phone: (573) 341-4841
Computing Services Fax: (573) 341-4216
--gKMricLos+KVdGMg
Content-Type: text/plain; charset=us-ascii
Content-Disposition: attachment; filename="auth-userok.diff"
Index: auth/userok.c
===================================================================
RCS file: /cvs/openafs/src/auth/userok.c,v
retrieving revision 1.3
diff -u -r1.3 userok.c
--- auth/userok.c 2000/11/05 03:25:14 1.3
+++ auth/userok.c 2001/05/11 15:05:23
@@ -35,6 +35,8 @@
#include <sys/stat.h>
#include <stdlib.h> /* for realpath() */
#include <errno.h>
+#include <string.h>
+#include <ctype.h>
#include <rx/xdr.h>
#include <rx/rx.h>
@@ -287,10 +289,52 @@
return code;
}
+/* special CompFindUser routine that builds up a princ and then
+ calls finduser on it. If found, returns char * to user string,
+ otherwise returns NULL. The resulting string should be immediately
+ copied to other storage prior to release of mutex. */
+static char *CompFindUser(adir, name, sep, inst, realm)
+ struct afsconf_dir *adir;
+ char *name;
+ char *sep;
+ char *inst;
+ char *realm;
+{
+ static char fullname[ MAXKTCNAMELEN + MAXKTCNAMELEN +
+ MAXKTCREALMLEN + 3 ];
+
+ /* always must have name */
+ if ( !name || !name[0] ) { return NULL; }
+ strcpy(fullname, name);
+
+ /* might have instance */
+ if ( inst && inst[0] ) {
+ if ( !sep || !sep[0] ) { return NULL; }
+
+ strcat(fullname, sep);
+ strcat(fullname, inst);
+ }
+
+ /* might have realm */
+ if ( realm && realm[0] )
+ {
+ strcat(fullname, "@");
+ strcat(fullname, realm);
+ }
+
+ if ( FindUser(adir, fullname) ) {
+ return fullname;
+ } else {
+ return NULL;
+ }
+}
+
+
/* make sure user authenticated on rx call acall is in list of valid
- users.
+ users. Copy the "real name" of the authenticated user into namep
+ if a pointer is passed.
*/
-afsconf_SuperUser(adir, acall, namep)
+afs_int32 afsconf_SuperUser(adir, acall, namep)
struct afsconf_dir *adir;
struct rx_call *acall;
char *namep; {
@@ -303,11 +347,13 @@
UNLOCK_GLOBAL_MUTEX
return 0;
}
+
if (afsconf_GetNoAuthFlag(adir)) {
- if (namep) strcpy(namep, "<noauth>");
+ if (namep) strcpy(namep, "<NoAuth>");
UNLOCK_GLOBAL_MUTEX
return 1;
}
+
tconn = rx_ConnectionOf(acall);
code = rx_SecurityClassOf(tconn);
if (code == 0) {
@@ -323,52 +369,26 @@
char tname[MAXKTCNAMELEN]; /* authentication from ticket */
char tinst[MAXKTCNAMELEN];
char tcell[MAXKTCREALMLEN];
- char uname[MAXKTCNAMELEN]; /* name.instance */
- int ilen; /* length of instance */
+ char tcell_l[MAXKTCREALMLEN];
+ char *tmp;
+
+ /* keep track of which one actually authorized request */
+ char uname[MAXKTCNAMELEN+MAXKTCNAMELEN+MAXKTCREALMLEN+3];
+
afs_uint32 exp;
- static char localcellname[MAXCELLCHARS] = "";
-#if defined(AFS_ATHENA_STDENV) || defined(AFS_KERBREALM_ENV)
- static char local_realm[AFS_REALM_SZ] = "";
-#endif
+ static char lcell[MAXCELLCHARS] = "";
+ static char lrealm[AFS_REALM_SZ] = "";
- /* des tokens */
+ /* get auth details from server connection */
code = rxkad_GetServerInfo
- (acall->conn, (afs_int32 *) 0, &exp, tname, tinst, tcell, (afs_int32 *) 0);
+ (acall->conn, (afs_int32 *) 0, &exp,
+ tname, tinst, tcell, (afs_int32 *) 0);
if (code) {
UNLOCK_GLOBAL_MUTEX
- return 0; /* bogus */
- }
-
- if (strlen (tcell)) {
- if (!localcellname[0])
- afsconf_GetLocalCell
- (adir, localcellname, sizeof(localcellname));
-#if defined(AFS_ATHENA_STDENV) || defined(AFS_KERBREALM_ENV)
- if (!local_realm[0]) {
- if (afs_krb_get_lrealm(local_realm, 0) != 0/*KSUCCESS*/)
- strncpy(local_realm, localcellname, AFS_REALM_SZ);
- }
- if (strcasecmp(local_realm, tcell) &&
- (strcasecmp(localcellname, tcell)))
-#else
- if (strcasecmp(localcellname, tcell))
-#endif
- {
- UNLOCK_GLOBAL_MUTEX
- return 0;
- }
+ return 0; /* bogus connection/other error */
}
- ilen = strlen(tinst);
- strncpy (uname, tname, sizeof(uname));
- if (ilen) {
- if (strlen(uname) + 1 + ilen >= sizeof(uname)) {
- UNLOCK_GLOBAL_MUTEX
- return 0;
- }
- strcat (uname, ".");
- strcat (uname, tinst);
- }
+ /* don't bother checking anything else if tix have expired */
#ifdef AFS_PTHREAD_ENV
if (exp < clock_Sec()) {
#else
@@ -376,15 +396,70 @@
#endif
UNLOCK_GLOBAL_MUTEX
return 0; /* expired tix */
+ }
+
+ /* generate lowercased version of cell name */
+ strcpy(tcell_l, tcell);
+ tmp = tcell_l;
+ while ( *tmp ) { *tmp = tolower(*tmp); *tmp++; }
+
+ /* determine local cell name. It's static, so will only get
+ calculated the first time through */
+ if (!lcell[0])
+ afsconf_GetLocalCell(adir, lcell, sizeof(lcell));
+
+ /* if running a krb environment, also get the local realm */
+ /* note - this assumes AFS_REALM_SZ <= MAXCELLCHARS */
+ /* just set it to lcell if it fails */
+ if (!lrealm[0]) {
+ if (afs_krb_get_lrealm(lrealm, 0) != 0) /* KSUCCESS */
+ strncpy(lrealm, lcell, AFS_REALM_SZ);
+ }
+
+
+ /* start with no uname and no authorization */
+ strcpy(uname, "");
+ flag = 0;
+
+ /* localauth special case */
+ if ( strlen(tinst) == 0 && strlen(tcell) == 0 &&
+ !strcmp(tname, AUTH_SUPERUSER) ) {
+ strcpy(uname, "<LocalAuth>");
+ flag = 1;
+
+ /* cell of connection matches local cell or krb4 realm */
+ } else if ( !strcasecmp(tcell, lcell) || !strcasecmp(tcell,lrealm) ) {
+ if ( (tmp = CompFindUser(adir, tname, ".", tinst, NULL)) ) {
+ strcpy(uname, tmp);
+ flag = 1;
+ } else if ( (tmp = CompFindUser(adir, tname, "/", tinst, NULL)) ) {
+ strcpy(uname, tmp);
+ flag = 1;
+ }
+
+ /* cell of conn doesn't match local cell or realm */
+ } else {
+ if ( (tmp = CompFindUser(adir, tname, ".", tinst, tcell)) ) {
+ strcpy(uname, tmp);
+ flag = 1;
+ } else if ( (tmp = CompFindUser(adir, tname, "/", tinst, tcell)) ) {
+ strcpy(uname, tmp);
+ flag = 1;
+ } else if ( (tmp = CompFindUser(adir, tname, ".", tinst, tcell_l)) ) {
+ strcpy(uname, tmp);
+ flag = 1;
+ } else if ( (tmp = CompFindUser(adir, tname, "/", tinst, tcell_l)) ) {
+ strcpy(uname, tmp);
+ flag = 1;
+ }
}
- if (strcmp(AUTH_SUPERUSER, uname) == 0) flag = 1;
- else flag = FindUser(adir, uname); /* true iff in userlist file */
+
if (namep)
strcpy(namep, uname);
UNLOCK_GLOBAL_MUTEX
return flag;
}
- else {
+ else { /* some other auth type */
UNLOCK_GLOBAL_MUTEX
return 0; /* mysterious, just say no */
}
--gKMricLos+KVdGMg--