userok: Allow NULL components in kerberosSuperUser
[openafs.git] / src / auth / userok.c
index fef5326..a8cb274 100644 (file)
@@ -1,7 +1,7 @@
 /*
  * Copyright 2000, International Business Machines Corporation and others.
  * All Rights Reserved.
- * 
+ *
  * This software has been released under the terms of the IBM Public
  * License.  For details, see the LICENSE file in the top-level source
  * directory or online at http://www.openafs.org/dl/license10.html
@@ -10,6 +10,7 @@
 #include <afsconfig.h>
 #include <afs/param.h>
 
+#include <roken.h>
 
 #include <afs/stds.h>
 #include <afs/pthread_glock.h>
@@ -29,7 +30,7 @@
 #include <errno.h>
 #include <string.h>
 #include <ctype.h>
-    
+
 #include <rx/xdr.h>
 #include <rx/rx.h>
 #include <stdio.h>
@@ -83,7 +84,7 @@ afsconf_GetNoAuthFlag(struct afsconf_dir *adir)
 void
 afsconf_SetNoAuthFlag(struct afsconf_dir *adir, int aflag)
 {
-    register afs_int32 code;
+    afs_int32 code;
 
     LOCK_GLOBAL_MUTEX;
     if (aflag == 0) {
@@ -106,18 +107,18 @@ afsconf_SetNoAuthFlag(struct afsconf_dir *adir, int aflag)
 
 /* deletes a user from the UserList file */
 int
-afsconf_DeleteUser(struct afsconf_dir *adir, register char *auser)
+afsconf_DeleteUser(struct afsconf_dir *adir, char *auser)
 {
     char tbuffer[1024];
     char nbuffer[1024];
-    register FILE *tf;
-    register FILE *nf;
-    register int flag;
+    FILE *tf;
+    FILE *nf;
+    int flag;
     char tname[64 + 1];
     char *tp;
     int found;
     struct stat tstat;
-    register afs_int32 code;
+    afs_int32 code;
 
     LOCK_GLOBAL_MUTEX;
     strcompose(tbuffer, sizeof tbuffer, adir->name, "/",
@@ -196,15 +197,15 @@ afsconf_DeleteUser(struct afsconf_dir *adir, register char *auser)
 
 /* returns nth super user from the UserList file */
 int
-afsconf_GetNthUser(struct afsconf_dir *adir, afs_int32 an, char *abuffer, 
+afsconf_GetNthUser(struct afsconf_dir *adir, afs_int32 an, char *abuffer,
                   afs_int32 abufferLen)
 {
     char tbuffer[256];
-    register FILE *tf;
+    FILE *tf;
     char tname[64 + 1];
-    register char *tp;
-    register int flag;
-    register afs_int32 code;
+    char *tp;
+    int flag;
+    afs_int32 code;
 
     LOCK_GLOBAL_MUTEX;
     strcompose(tbuffer, sizeof tbuffer, adir->name, "/",
@@ -235,13 +236,13 @@ afsconf_GetNthUser(struct afsconf_dir *adir, afs_int32 an, char *abuffer,
 
 /* returns true iff user is in the UserList file */
 static int
-FindUser(struct afsconf_dir *adir, register char *auser)
+FindUser(struct afsconf_dir *adir, char *auser)
 {
     char tbuffer[256];
-    register bufio_p bp;
+    bufio_p bp;
     char tname[64 + 1];
-    register int flag;
-    register afs_int32 code;
+    int flag;
+    afs_int32 code;
     int rc;
 
     strcompose(tbuffer, sizeof tbuffer, adir->name, "/", AFSDIR_ULIST_FILE,
@@ -270,7 +271,7 @@ int
 afsconf_AddUser(struct afsconf_dir *adir, char *aname)
 {
     FILE *tf;
-    register afs_int32 code;
+    afs_int32 code;
     char tbuffer[256];
 
     LOCK_GLOBAL_MUTEX;
@@ -297,11 +298,11 @@ afsconf_AddUser(struct afsconf_dir *adir, char *aname)
 }
 
 /* special CompFindUser routine that builds up a princ and then
-       calls finduser on it. If found, returns char * to user string, 
+       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(struct afsconf_dir *adir, char *name, char *sep, char *inst, 
+CompFindUser(struct afsconf_dir *adir, char *name, char *sep, char *inst,
             char *realm)
 {
     static char fullname[MAXKTCNAMELEN + MAXKTCNAMELEN + MAXKTCREALMLEN + 3];
@@ -335,6 +336,142 @@ CompFindUser(struct afsconf_dir *adir, char *name, char *sep, char *inst,
     }
 }
 
+static int
+kerberosSuperUser(struct afsconf_dir *adir, char *tname, char *tinst,
+                 char *tcell, char *namep)
+{
+    char tcell_l[MAXKTCREALMLEN] = "";
+    char *tmp;
+
+    /* keep track of which one actually authorized request */
+    char uname[MAXKTCNAMELEN + MAXKTCNAMELEN + MAXKTCREALMLEN + 3];
+
+    static char lcell[MAXCELLCHARS] = "";
+    static char lrealms[AFS_NUM_LREALMS][AFS_REALM_SZ];
+    static int  num_lrealms = -1;
+    int lrealm_match = 0, i;
+    int flag;
+
+    /* generate lowercased version of cell name */
+    if (tcell) {
+       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 (num_lrealms == -1) {
+       for (i=0; i<AFS_NUM_LREALMS; i++) {
+           if (afs_krb_get_lrealm(lrealms[i], i) != 0 /*KSUCCESS*/)
+               break;
+       }
+
+       if (i == 0) {
+           strncpy(lrealms[0], lcell, AFS_REALM_SZ);
+           num_lrealms = 1;
+       } else {
+           num_lrealms = i;
+       }
+    }
+
+    /* See if the ticket cell matches one of the local realms */
+    lrealm_match = 0;
+    for ( i=0;i<num_lrealms;i++ ) {
+       if (!strcasecmp(lrealms[i], tcell)) {
+           lrealm_match = 1;
+           break;
+       }
+    }
+
+    /* If yes, then make sure that the name is not present in
+     * an exclusion list */
+    if (lrealm_match) {
+       if (tinst && tinst[0])
+           snprintf(uname,sizeof(uname),"%s.%s@%s",tname,tinst,tcell);
+       else
+           snprintf(uname,sizeof(uname),"%s@%s",tname,tcell);
+
+       if (afs_krb_exclusion(uname))
+           lrealm_match = 0;
+    }
+
+    /* start with no uname and no authorization */
+    strcpy(uname, "");
+    flag = 0;
+
+    /* localauth special case */
+    if ((tinst == NULL || strlen(tinst) == 0) &&
+       (tcell == NULL || strlen(tcell) == 0)
+       && !strcmp(tname, AUTH_SUPERUSER)) {
+       strcpy(uname, "<LocalAuth>");
+       flag = 1;
+
+       /* cell of connection matches local cell or one of the realms */
+    } else if (!strcasecmp(tcell, lcell) || lrealm_match) {
+       if ((tmp = CompFindUser(adir, tname, ".", tinst, NULL))) {
+           strcpy(uname, tmp);
+           flag = 1;
+#ifdef notyet
+       } else if ((tmp = CompFindUser(adir, tname, "/", tinst, NULL))) {
+           strcpy(uname, tmp);
+           flag = 1;
+#endif
+       }
+       /* cell of conn doesn't match local cell or realm */
+    } else {
+       if ((tmp = CompFindUser(adir, tname, ".", tinst, tcell))) {
+           strcpy(uname, tmp);
+           flag = 1;
+#ifdef notyet
+       } else if ((tmp = CompFindUser(adir, tname, "/", tinst, tcell))) {
+           strcpy(uname, tmp);
+           flag = 1;
+#endif
+       } else if ((tmp = CompFindUser(adir, tname, ".", tinst, tcell_l))) {
+           strcpy(uname, tmp);
+           flag = 1;
+#ifdef notyet
+       } else if ((tmp = CompFindUser(adir, tname, "/", tinst, tcell_l))) {
+           strcpy(uname, tmp);
+           flag = 1;
+#endif
+       }
+    }
+
+    if (namep)
+       strcpy(namep, uname);
+
+    return flag;
+}
+
+static int
+rxkadSuperUser(struct afsconf_dir *adir, struct rx_call *acall, char *namep)
+{
+    char tname[MAXKTCNAMELEN]; /* authentication from ticket */
+    char tinst[MAXKTCNAMELEN];
+    char tcell[MAXKTCREALMLEN];
+
+    afs_uint32 exp;
+    int code;
+
+    /* get auth details from server connection */
+    code = rxkad_GetServerInfo(acall->conn, NULL, &exp, tname, tinst, tcell,
+                              NULL);
+    if (code)
+       return 0;               /* bogus connection/other error */
+
+    return kerberosSuperUser(adir, tname, tinst, tcell, namep);
+}
 
 /* make sure user authenticated on rx call acall is in list of valid
     users. Copy the "real name" of the authenticated user into namep
@@ -343,8 +480,8 @@ CompFindUser(struct afsconf_dir *adir, char *name, char *sep, char *inst,
 afs_int32
 afsconf_SuperUser(struct afsconf_dir *adir, struct rx_call *acall, char *namep)
 {
-    register struct rx_connection *tconn;
-    register afs_int32 code;
+    struct rx_connection *tconn;
+    afs_int32 code;
     int flag;
 
     LOCK_GLOBAL_MUTEX;
@@ -370,135 +507,7 @@ afsconf_SuperUser(struct afsconf_dir *adir, struct rx_call *acall, char *namep)
        UNLOCK_GLOBAL_MUTEX;
        return 0;               /* not supported any longer */
     } else if (code == 2) {
-       char tname[MAXKTCNAMELEN];      /* authentication from ticket */
-       char tinst[MAXKTCNAMELEN];
-       char tcell[MAXKTCREALMLEN];
-       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 lcell[MAXCELLCHARS] = "";
-       static char lrealms[AFS_NUM_LREALMS][AFS_REALM_SZ];
-       static int  num_lrealms = -1;
-       int lrealm_match = 0, i;
-
-       /* get auth details from server connection */
-       code =
-           rxkad_GetServerInfo(acall->conn, NULL, &exp, tname, tinst, tcell,
-                               NULL);
-       if (code) {
-           UNLOCK_GLOBAL_MUTEX;
-           return 0;           /* bogus connection/other error */
-       }
-
-       /* don't bother checking anything else if tix have expired */
-#ifdef AFS_PTHREAD_ENV
-       if (exp < clock_Sec()) {
-#else
-       if (exp < FT_ApproxTime()) {
-#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 (num_lrealms == -1) {
-           for (i=0; i<AFS_NUM_LREALMS; i++) {
-               if (afs_krb_get_lrealm(lrealms[i], i) != 0 /*KSUCCESS*/)
-                   break;
-           }
-
-           if (i == 0) {
-               strncpy(lrealms[0], lcell, AFS_REALM_SZ);
-               num_lrealms = 1;
-           } else {
-               num_lrealms = i;
-           }
-       }
-
-       /* See if the ticket cell matches one of the local realms */
-       lrealm_match = 0;
-       for ( i=0;i<num_lrealms;i++ ) {
-           if (!strcasecmp(lrealms[i], tcell)) {
-               lrealm_match = 1;
-               break;
-           }
-       }
-
-       /* If yes, then make sure that the name is not present in 
-        * an exclusion list */
-       if (lrealm_match) {
-           if (tinst[0])
-               snprintf(uname,sizeof(uname),"%s.%s@%s",tname,tinst,tcell);
-           else
-               snprintf(uname,sizeof(uname),"%s@%s",tname,tcell);
-
-           if (afs_krb_exclusion(uname))
-               lrealm_match = 0;
-       }
-
-       /* 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 one of the realms */
-       } else if (!strcasecmp(tcell, lcell) || lrealm_match) {
-           if ((tmp = CompFindUser(adir, tname, ".", tinst, NULL))) {
-               strcpy(uname, tmp);
-               flag = 1;
-#ifdef notyet
-           } else if ((tmp = CompFindUser(adir, tname, "/", tinst, NULL))) {
-               strcpy(uname, tmp);
-               flag = 1;
-#endif
-           }
-           /* cell of conn doesn't match local cell or realm */
-       } else {
-           if ((tmp = CompFindUser(adir, tname, ".", tinst, tcell))) {
-               strcpy(uname, tmp);
-               flag = 1;
-#ifdef notyet
-           } else if ((tmp = CompFindUser(adir, tname, "/", tinst, tcell))) {
-               strcpy(uname, tmp);
-               flag = 1;
-#endif
-           } else if ((tmp = CompFindUser(adir, tname, ".", tinst, tcell_l))) {
-               strcpy(uname, tmp);
-               flag = 1;
-#ifdef notyet
-           } else if ((tmp = CompFindUser(adir, tname, "/", tinst, tcell_l))) {
-               strcpy(uname, tmp);
-               flag = 1;
-#endif
-           }
-       }
-
-       if (namep)
-           strcpy(namep, uname);
+       flag = rxkadSuperUser(adir, acall, namep);
        UNLOCK_GLOBAL_MUTEX;
        return flag;
     } else {                   /* some other auth type */