multiple-local-realms-20051208
authorJeffrey Altman <jaltman@secure-endpoints.com>
Thu, 15 Dec 2005 05:51:24 +0000 (05:51 +0000)
committerJeffrey Altman <jaltman@secure-endpoints.com>
Thu, 15 Dec 2005 05:51:24 +0000 (05:51 +0000)
This patch extends the krb.conf file allowing the specification of
multiple realms which should be treated as equivalents to the local
cell authentication domain.  Additional realms are specified on the
first line of the krb.conf file and are separated by white space.

In addition, the patch adds a new file stored in the same directory
as the krb.conf file called krb.excl.  This file contains a list of
principal names, one per line, that must not be treated as local
identities.

The purpose of this patch is to allow organizations that are supporting
multiple realms with synchronized user principal databases to allow
their users to login with any of the realms and treat the principal
names as equivalent to the local PTS identity.   The exclusion is
to allow certain names, such as those for administrative IDs, to be
restricted to a subset of the realms.

Further optimization of the afs_krb_exclusion() should be performed to
remove the need to re-read the file.  This patch should be considered
a temporary solution until a more permanent set of extensions to the
PT database and RPCs allow for the assignment of mechanism specific
aliases for PT IDs.

====================
This delta was composed from multiple commits as part of the CVS->Git migration.
The checkin message with each commit was inconsistent.
The following are the additional commit messages.
====================

correction to exclusion list parsing

12 files changed:
src/audit/audit.c
src/auth/userok.c
src/config/afs_sysnames.h
src/libafsauthent/afsauthent.def
src/ptserver/ptprocs.c
src/util/afsutil_prototypes.h
src/util/dirpath.c
src/util/dirpath_nt.h
src/util/get_krbrlm.c
src/util/test/dirpath_test.c
src/viced/host.c
src/viced/viced.c

index aeea185..7fe3f9a 100644 (file)
@@ -420,12 +420,43 @@ osi_auditU(struct rx_call *call, char *audEvent, int errCode, ...)
                     }
                     if ((clen = strlen(tcell))) {
 #if defined(AFS_ATHENA_STDENV) || defined(AFS_KERBREALM_ENV)
-                        static char local_realm[AFS_REALM_SZ] = "";
-                        if (!local_realm[0]) {
-                            if (afs_krb_get_lrealm(local_realm, 0) != 0 /*KSUCCESS*/)
-                                strncpy(local_realm, "UNKNOWN.LOCAL.REALM", AFS_REALM_SZ);
+                        static char local_realms[AFS_NUM_LREALMS][AFS_REALM_SZ];
+                       static int  num_lrealms = -1;
+                       int i, lrealm_match;
+
+                       if (num_lrealms == -1) {
+                           for (i=0; i<AFS_NUM_LREALMS; i++) {
+                               if (afs_krb_get_lrealm(local_realms[i], i) != 0 /*KSUCCESS*/)
+                                   break;
+                           }
+
+                           if (i=0)
+                               strncpy(local_realms[0], "UNKNOWN.LOCAL.REALM", AFS_REALM_SZ);
+                           num_lrealms = i;
                         }
-                        if (strcasecmp(local_realm, tcell)) {
+
+                       /* Check to see if the ticket cell matches one of the local realms */
+                       lrealm_match = 0;
+                       for ( i=0;i<num_lrealms;i++ ) {
+                           if (!strcasecmp(local_realms[i], tcell)) {
+                               lrealm_match = 1;
+                               break;
+                           }
+                       }
+                       /* If yes, then make sure that the name is not present in 
+                        * an exclusion list */
+                       if (lrealm_match) {
+                           char uname[256];
+                           if (inst[0])
+                               snprintf(uname,sizeof(uname),"%s.%s@%s",name,inst,tcell);
+                           else
+                               snprintf(uname,sizeof(uname),"%s@%s",name,tcell);
+
+                           if (afs_krb_exclusion(uname))
+                               lrealm_match = 0;
+                       }
+
+                       if (!lrealm_match) {    
                             if (strlen(vname) + 1 + clen >= sizeof(vname))
                                 goto done;
                             strcat(vname, "@");
index 09da2e0..b37385f 100644 (file)
@@ -403,7 +403,9 @@ afsconf_SuperUser(adir, acall, namep)
 
        afs_uint32 exp;
        static char lcell[MAXCELLCHARS] = "";
-       static char lrealm[AFS_REALM_SZ] = "";
+       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 =
@@ -440,11 +442,40 @@ afsconf_SuperUser(adir, acall, namep)
        /* 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);
+       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, "");
@@ -456,8 +487,8 @@ afsconf_SuperUser(adir, acall, namep)
            strcpy(uname, "<LocalAuth>");
            flag = 1;
 
-           /* cell of connection matches local cell or krb4 realm */
-       } else if (!strcasecmp(tcell, lcell) || !strcasecmp(tcell, lrealm)) {
+           /* 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;
@@ -467,7 +498,6 @@ afsconf_SuperUser(adir, acall, namep)
                flag = 1;
 #endif
            }
-
            /* cell of conn doesn't match local cell or realm */
        } else {
            if ((tmp = CompFindUser(adir, tname, ".", tinst, tcell))) {
index b54fc4f..94c5076 100644 (file)
 #ifdef AFS_KERBREALM_ENV
 #define        AFS_REALM_SZ            64
 #endif
+/* Specifies the number of equivalent local realm names */
+#define AFS_NUM_LREALMS         4
 #endif /* __AFS_SYSNAMES_INCL_ENV_ */
index a822985..86f2437 100644 (file)
@@ -63,7 +63,7 @@ EXPORTS
        pr_GetCPS                                       @62
        pr_Initialize                                   @63
        pr_GetHostCPS                                   @64
-       afs_krb_get_lrealm                              @65
+;      afs_krb_get_lrealm                              @65
        pr_NameToId                                     @66
        pr_IdToName                                     @67
        afs_gettimeofday                                @68
@@ -78,8 +78,8 @@ EXPORTS
        pioctl                                          @77
        rx_Init                                         @78
        ka_UserAuthenticateGeneral2                     @79
-    pr_CreateUser                   @80
-    pr_SNameToId                    @81
+       pr_CreateUser                                   @80
+       pr_SNameToId                                    @81
 
 
        DISK_function_names                             @83 DATA
index cb006e6..fd031b9 100644 (file)
@@ -93,6 +93,7 @@ extern struct ubik_dbase *dbase;
 extern afs_int32 Initdb();
 extern int pr_noAuth;
 extern afs_int32 initd;
+extern char *pr_realmName;
 afs_int32 iNewEntry(), newEntry(), whereIsIt(), dumpEntry(), addToGroup(),
 nameToID(), Delete(), removeFromGroup();
 afs_int32 getCPS(), getCPS2(), getHostCPS(), listMax(), setMax(), listEntry();
@@ -179,22 +180,9 @@ WhoIsThis(acall, at, aid)
        if (exp < FT_ApproxTime())
            goto done;
 #endif
-       if (strlen(tcell)) {
-           extern char *pr_realmName;
-#if    defined(AFS_ATHENA_STDENV) || defined(AFS_KERBREALM_ENV)
-           static char local_realm[AFS_REALM_SZ] = "";
-           if (!local_realm[0]) {
-               if (afs_krb_get_lrealm(local_realm, 0) != 0 /*KSUCCESS*/)
-                   strncpy(local_realm, pr_realmName, AFS_REALM_SZ);
-           }
-#endif
-           if (
-#if    defined(AFS_ATHENA_STDENV) || defined(AFS_KERBREALM_ENV)
-                  strcasecmp(local_realm, tcell) &&
-#endif
-                  strcasecmp(pr_realmName, tcell))
-               foreign = 1;
-       }
+       if (tcell[0])
+           foreign = afs_is_foreign_ticket_name(tcell,name,inst,pr_realmName);
+
        strncpy(vname, name, sizeof(vname));
        if (ilen = strlen(inst)) {
            if (strlen(vname) + 1 + ilen >= sizeof(vname))
@@ -2295,7 +2283,6 @@ addWildCards(tt, alist, host)
 }
 #endif /* IP_WILDCARDS */
 
-
 afs_int32
 WhoIsThisWithName(acall, at, aid, aname)
      struct rx_call *acall;
@@ -2323,11 +2310,12 @@ WhoIsThisWithName(acall, at, aid, aname)
     } else if (code == 2) {    /* kad class */
 
        int clen;
-       extern char *pr_realmName;
 
        if ((code = rxkad_GetServerInfo(acall->conn, NULL, 0 /*was &exp */ ,
                                        name, inst, tcell, NULL)))
            goto done;
+
+
        strncpy(vname, name, sizeof(vname));
        if ((ilen = strlen(inst))) {
            if (strlen(vname) + 1 + ilen >= sizeof(vname))
@@ -2336,19 +2324,9 @@ WhoIsThisWithName(acall, at, aid, aname)
            strcat(vname, inst);
        }
        if ((clen = strlen(tcell))) {
+           int foreign = afs_is_foreign_ticket_name(tcell,name,inst,pr_realmName);
 
-#if    defined(AFS_ATHENA_STDENV) || defined(AFS_KERBREALM_ENV)
-           static char local_realm[AFS_REALM_SZ] = "";
-           if (!local_realm[0]) {
-               if (afs_krb_get_lrealm(local_realm, 0) != 0 /*KSUCCESS*/)
-                   strncpy(local_realm, pr_realmName, AFS_REALM_SZ);
-           }
-#endif
-           if (
-#if    defined(AFS_ATHENA_STDENV) || defined(AFS_KERBREALM_ENV)
-                  strcasecmp(local_realm, tcell) &&
-#endif
-                  strcasecmp(pr_realmName, tcell)) {
+           if (foreign) {
                if (strlen(vname) + 1 + clen >= sizeof(vname))
                    goto done;
                strcat(vname, "@");
index fbfc35f..a3151fc 100644 (file)
@@ -74,7 +74,8 @@ extern int64_t flipbase64_to_int64(char *s);
 
 /* get_krbrlm.c */
 extern int afs_krb_get_lrealm(char *r, int n);
-
+extern int afs_krb_exclusion(char *name);
+extern int afs_is_foreign_ticket_name(char *tcell, char *tname, char *tinst, char *localrealm);
 /* hostparse.c */
 extern struct hostent *hostutil_GetHostByName(register char *ahost);
 extern char *hostutil_GetNameByINet(afs_uint32 addr);
index 82e89b7..ff856f9 100644 (file)
@@ -365,6 +365,8 @@ initDirPathArray(void)
     pathp = dirPathArray[AFSDIR_SERVER_MIGRATELOG_FILEPATH_ID];
     AFSDIR_SERVER_FILEPATH(pathp, AFSDIR_MIGR_DIR, AFSDIR_MIGRATE_LOGNAME);
 
+    pathp = dirPathArray[AFSDIR_SERVER_KRB_EXCL_FILEPATH_ID];
+    AFSDIR_SERVER_FILEPATH(pathp, AFSDIR_SERVER_ETC_DIR, AFSDIR_KRB_EXCL_FILE);
 
     /* client file paths */
 #ifdef AFS_NT40_ENV
index 230e062..b0c62bc 100644 (file)
@@ -135,6 +135,7 @@ extern int
 #define AFSDIR_BOSVR_FILE       "bosserver"
 #define AFSDIR_VOLSERLOG_FILE   "VolserLog"
 #define AFSDIR_AUDIT_FILE       "Audit"
+#define AFSDIR_KRB_EXCL_FILE    "krb.excl"
 
 #define AFSDIR_ROOTVOL_FILE     "RootVolume"
 #define AFSDIR_HOSTDUMP_FILE    "hosts.dump"
@@ -257,6 +258,7 @@ typedef enum afsdir_id {
     AFSDIR_SERVER_MIGRATELOG_FILEPATH_ID,
     AFSDIR_SERVER_BIN_FILE_DIRPATH_ID,
     AFSDIR_CLIENT_CELLALIAS_FILEPATH_ID,
+    AFSDIR_SERVER_KRB_EXCL_FILEPATH_ID,
     AFSDIR_PATHSTRING_MAX
 } afsdir_id_t;
 
@@ -325,6 +327,7 @@ const char *getDirPath(afsdir_id_t string_id);
 #define AFSDIR_SERVER_WEIGHTING_CONSTANTS_FILEPATH getDirPath(AFSDIR_SERVER_WEIGHTING_CONSTANTS_FILEPATH_ID)
 #define AFSDIR_SERVER_THRESHOLD_CONSTANTS_FILEPATH getDirPath(AFSDIR_SERVER_THRESHOLD_CONSTANTS_FILEPATH_ID)
 #define AFSDIR_SERVER_MIGRATELOG_FILEPATH getDirPath(AFSDIR_SERVER_MIGRATELOG_FILEPATH_ID)
+#define AFSDIR_SERVER_KRB_EXCL_FILEPATH getDirPath(AFSDIR_SERVER_KRB_EXCL_FILEPATH_ID)
 
 /* client file paths */
 #define AFSDIR_CLIENT_THISCELL_FILEPATH getDirPath(AFSDIR_CLIENT_THISCELL_FILEPATH_ID)
index 0c6769a..b707954 100644 (file)
@@ -26,21 +26,148 @@ RCSID
 #define        KSUCCESS        0
 #define        KFAILURE        (-1)
 
+static char *
+parse_str(char *buffer, char *result, int size)
+{
+    int n=0;
+
+    if (!buffer)
+        goto cleanup;
+
+    while (*buffer && isspace(*buffer))
+        buffer++;
+    while (*buffer && !isspace(*buffer)) {
+       if (n < size - 1) {
+           *result++=*buffer++;
+           n++;
+       } else {
+           buffer++;
+       }
+    }
+
+  cleanup:
+    *result='\0';
+    return buffer;
+}
+
+
 int
 afs_krb_get_lrealm(char *r, int n)
 {
+    char linebuf[2048];
+    char tr[AFS_REALM_SZ] = "";
+    char *p;
     FILE *cnffile/*, *fopen()*/;
+    int i;
+    int rv = KFAILURE;
 
-    if (n > 1)
-       return (KFAILURE);      /* Temporary restriction */
+    *r = '\0';
 
     if ((cnffile = fopen(AFSDIR_SERVER_KCONF_FILEPATH, "r")) == NULL) {
        return (KFAILURE);
     }
-    if (fscanf(cnffile, "%s", r) != 1) {
-       (void)fclose(cnffile);
-       return (KFAILURE);
+    if (fgets(linebuf, sizeof(linebuf)-1, cnffile) == NULL) {
+       goto cleanup;
+    }
+    linebuf[sizeof(linebuf)-1] = '\0';
+    for (i=0, p=linebuf; i<=n && *p; i++) {
+        p = parse_str(p, tr, AFS_REALM_SZ);
     }
+
+    if (*tr) {
+       strcpy(r,tr);
+       rv = KSUCCESS;
+    }
+
+  cleanup:
     (void)fclose(cnffile);
-    return (KSUCCESS);
+    return rv;
 }
+
+int
+afs_krb_exclusion(char * name)
+{
+    char linebuf[2048];
+    char excl_name[256] = "";
+    FILE *cnffile/*, *fopen()*/;
+    int exclude = 0;
+
+    if ((cnffile = fopen(AFSDIR_SERVER_KRB_EXCL_FILEPATH, "r")) == NULL)
+       return exclude;
+
+    for (;;) {
+       if (fgets(linebuf, sizeof(linebuf)-1, cnffile) == NULL) {
+           goto cleanup;
+       }
+       linebuf[sizeof(linebuf)-1] = '\0';
+        parse_str(linebuf, excl_name, sizeof(excl_name));
+
+       if (!strcmp(name,excl_name)) {
+           exclude = 1;
+           break;
+       }
+    }
+
+  cleanup:
+    (void)fclose(cnffile);
+    return exclude;
+}
+
+int 
+afs_is_foreign_ticket_name(char *tcell, char *tname, char *tinst, char *localrealm)
+{
+    int foreign = 0;
+
+    if (localrealm && strcasecmp(localrealm, tcell))
+       foreign = 1;
+
+#if    defined(AFS_ATHENA_STDENV) || defined(AFS_KERBREALM_ENV)
+    if (!foreign) {
+       static char local_realms[AFS_NUM_LREALMS][AFS_REALM_SZ];
+       static int  num_lrealms = -1;
+       int lrealm_match, i;
+       char uname[256];
+
+       if (num_lrealms == -1) {
+           for (i=0; i<AFS_NUM_LREALMS; i++) {
+               if (afs_krb_get_lrealm(local_realms[i], i) != 0 /*KSUCCESS*/)
+                   break;
+           }
+
+           if (i=0 && localrealm) {
+               strncpy(local_realms[0], localrealm, 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(local_realms[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;
+       }
+
+       foreign = !lrealm_match;
+    }
+#endif
+    return foreign;
+}
+
+
+
index 1bf1405..b0584b7 100644 (file)
@@ -124,6 +124,8 @@ main(int argc, char *argv[])
           AFSDIR_SERVER_FILELOG_FILEPATH);
     printf("AFSDIR_SERVER_AUDIT_FILEPATH = %s\n",
           AFSDIR_SERVER_AUDIT_FILEPATH);
+    printf("AFSDIR_SERVER_KRB_EXCL_FILEPATH  = %s\n",
+          AFSDIR_SERVER_KRB_EXCL_FILEPATH);
     printf("\n");
     printf("\n");
     printf("AFSDIR_CLIENT_THISCELL_FILEPATH = %s\n",
index c768188..6b7eb80 100644 (file)
@@ -1348,20 +1348,34 @@ h_GetHost_r(struct rx_connection *tcon)
 
 
 static char localcellname[PR_MAXNAMELEN + 1];
-char local_realm[AFS_REALM_SZ] = "";
+char local_realms[AFS_NUM_LREALMS][AFS_REALM_SZ];
+int  num_lrealms = -1;
 
 /* not reentrant */
 void
 h_InitHostPackage()
 {
     afsconf_GetLocalCell(confDir, localcellname, PR_MAXNAMELEN);
-    if (!local_realm[0]) {
-       if (afs_krb_get_lrealm(local_realm, 0) != 0 /*KSUCCESS*/) {
+    if (num_lrealms == -1) {
+       int i;
+       for (i=0; i<AFS_NUM_LREALMS; i++) {
+           if (afs_krb_get_lrealm(local_realms[i], i) != 0 /*KSUCCESS*/)
+               break;
+       }
+
+       if (i=0) {
            ViceLog(0,
                    ("afs_krb_get_lrealm failed, using %s.\n",
                     localcellname));
-           strcpy(local_realm, localcellname);
+           strncpy(local_realms[0], localcellname, AFS_REALM_SZ);
+           num_lrealms = i =1;
+       } else {
+           num_lrealms = i;
        }
+
+       /* initialize the rest of the local realms to nullstring for debugging */
+       for (; i<AFS_NUM_LREALMS; i++)
+           local_realms[i][0] = '\0';
     }
     rxcon_ident_key = rx_KeyCreate((rx_destructor_t) free);
     rxcon_client_key = rx_KeyCreate((rx_destructor_t) 0);
@@ -1391,11 +1405,10 @@ MapName_r(char *aname, char *acell, afs_int32 * aval)
 
     cnamelen = strlen(acell);
     if (cnamelen) {
-       if (strcasecmp(local_realm, acell)
-           && strcasecmp(localcellname, acell)) {
+       if (afs_is_foreign_ticket_name(aname, "", acell, localcellname)) {
            ViceLog(2,
-                   ("MapName: cell is foreign.  cell=%s, localcell=%s, localrealm=%s\n",
-                    acell, localcellname, local_realm));
+                   ("MapName: cell is foreign.  cell=%s, localcell=%s, localrealms={%s,%s,%s,%s}\n",
+                   acell, localcellname, local_realms[0],local_realms[1],local_realms[2],local_realms[3]));
            if ((anamelen + cnamelen + 1) >= PR_MAXNAMELEN) {
                ViceLog(2,
                        ("MapName: Name too long, using AnonymousID for %s@%s\n",
index 9d34351..517ccd5 100644 (file)
@@ -1052,7 +1052,8 @@ ParseArgs(int argc, char *argv[])
        else if (!strcmp(argv[i], "-nojumbo")) {
            rxJumbograms = 0;
        } else if (!strcmp(argv[i], "-realm")) {
-           extern char local_realm[AFS_REALM_SZ];
+           extern char local_realms[AFS_NUM_LREALMS][AFS_REALM_SZ];
+           extern int  num_lrealms;
            if ((i + 1) >= argc) {
                fprintf(stderr, "missing argument for -realm\n"); 
                return -1; 
@@ -1063,7 +1064,15 @@ ParseArgs(int argc, char *argv[])
                     AFS_REALM_SZ);
                return -1;
            }
-           strncpy(local_realm, argv[i], AFS_REALM_SZ);
+           if (num_lrealms == -1) 
+               num_lrealms = 0;
+           if (num_lrealms >= AFS_NUM_LREALMS) {
+               printf
+                   ("a maximum of %d -realm arguments can be specified.\n",
+                    AFS_NUM_LREALMS);
+               return -1;
+           }
+           strncpy(local_realms[num_lrealms++], argv[i], AFS_REALM_SZ);
        } else if (!strcmp(argv[i], "-udpsize")) {
            if ((i + 1) >= argc) {
                printf("You have to specify -udpsize <integer value>\n");