From c8c62a231b8a6a31771cb561128824375dc67a10 Mon Sep 17 00:00:00 2001 From: Russ Allbery Date: Fri, 27 Jun 2008 22:07:44 -0700 Subject: [PATCH] Allow multiple local realms in krb.conf Apply quilt patch multiple-local-realms: Enable listing multiple realms in the server krb.conf file. Up to four realms may be treated as local in that fashion for authorization purposes (instead of the single realm supported without this patch). This upstream patch is in the 1.5 series but not in 1.4. However, it has been working in production at Stanford University for some time. --- src/audit/audit.c | 41 ++++++++-- src/auth/userok.c | 44 +++++++++-- src/config/afs_sysnames.h | 2 + src/ptserver/ptprocs.c | 57 +++++++------- src/util/afsutil_prototypes.h | 3 +- src/util/dirpath.c | 2 + src/util/dirpath.hin | 3 + src/util/dirpath_nt.h | 3 + src/util/get_krbrlm.c | 139 ++++++++++++++++++++++++++++++++-- src/util/test/dirpath_test.c | 2 + src/viced/host.c | 29 +++++-- src/viced/viced.c | 13 +++- 12 files changed, 278 insertions(+), 60 deletions(-) diff --git a/src/audit/audit.c b/src/audit/audit.c index f0f76dfbf..42f17aeea 100644 --- a/src/audit/audit.c +++ b/src/audit/audit.c @@ -447,12 +447,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= sizeof(vname)) goto done; strcat(vname, "@"); diff --git a/src/auth/userok.c b/src/auth/userok.c index 7ecb9bad2..5553a4be8 100644 --- a/src/auth/userok.c +++ b/src/auth/userok.c @@ -382,7 +382,9 @@ afsconf_SuperUser(struct afsconf_dir *adir, struct rx_call *acall, char *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 = @@ -419,11 +421,40 @@ afsconf_SuperUser(struct afsconf_dir *adir, struct rx_call *acall, char *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"); 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; @@ -446,7 +477,6 @@ afsconf_SuperUser(struct afsconf_dir *adir, struct rx_call *acall, char *namep) flag = 1; #endif } - /* cell of conn doesn't match local cell or realm */ } else { if ((tmp = CompFindUser(adir, tname, ".", tinst, tcell))) { diff --git a/src/config/afs_sysnames.h b/src/config/afs_sysnames.h index 4fdeac5e2..faed0bd7e 100644 --- a/src/config/afs_sysnames.h +++ b/src/config/afs_sysnames.h @@ -291,4 +291,6 @@ #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_ */ diff --git a/src/ptserver/ptprocs.c b/src/ptserver/ptprocs.c index f3240bb66..7bf5cde5c 100644 --- a/src/ptserver/ptprocs.c +++ b/src/ptserver/ptprocs.c @@ -87,6 +87,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(); @@ -172,22 +173,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(name,inst,tcell,pr_realmName); + strncpy(vname, name, sizeof(vname)); if (ilen = strlen(inst)) { if (strlen(vname) + 1 + ilen >= sizeof(vname)) @@ -634,7 +622,24 @@ nameToID(call, aname, aid) ABORT_WITH(tt, code); for (i = 0; i < aname->namelist_len; i++) { - code = NameToID(tt, aname->namelist_val[i], &aid->idlist_val[i]); + char vname[256]; + char *nameinst, *cell; + + strncpy(vname, aname->namelist_val[i], sizeof(vname)); + vname[sizeof(vname)-1] ='\0'; + + nameinst = vname; + cell = strchr(vname, '@'); + if (cell) { + *cell = '\0'; + cell++; + } + + if (cell && afs_is_foreign_ticket_name(nameinst,NULL,cell,pr_realmName)) + code = NameToID(tt, aname->namelist_val[i], &aid->idlist_val[i]); + else + code = NameToID(tt, nameinst, &aid->idlist_val[i]); + if (code != PRSUCCESS) aid->idlist_val[i] = ANONYMOUSID; osi_audit(PTS_NmToIdEvent, code, AUD_STR, @@ -2275,7 +2280,6 @@ addWildCards(tt, alist, host) } #endif /* IP_WILDCARDS */ - afs_int32 WhoIsThisWithName(acall, at, aid, aname) struct rx_call *acall; @@ -2303,11 +2307,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)) @@ -2316,19 +2321,9 @@ WhoIsThisWithName(acall, at, aid, aname) strcat(vname, inst); } if ((clen = strlen(tcell))) { + int foreign = afs_is_foreign_ticket_name(name,inst,tcell,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, "@"); diff --git a/src/util/afsutil_prototypes.h b/src/util/afsutil_prototypes.h index ab597783f..55a706866 100644 --- a/src/util/afsutil_prototypes.h +++ b/src/util/afsutil_prototypes.h @@ -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 *tname, char *tinst, char * tcell, char *localrealm); /* hostparse.c */ extern struct hostent *hostutil_GetHostByName(register char *ahost); extern char *hostutil_GetNameByINet(afs_uint32 addr); diff --git a/src/util/dirpath.c b/src/util/dirpath.c index e915e1334..1130cd198 100644 --- a/src/util/dirpath.c +++ b/src/util/dirpath.c @@ -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 diff --git a/src/util/dirpath.hin b/src/util/dirpath.hin index b94d8d7b6..23590ad4a 100644 --- a/src/util/dirpath.hin +++ b/src/util/dirpath.hin @@ -144,6 +144,7 @@ ConstructLocalLogPath(const char *cpath, #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" @@ -262,6 +263,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; /* getDirPath() returns a pointer to a string from an internal array of path strings @@ -329,6 +331,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) diff --git a/src/util/dirpath_nt.h b/src/util/dirpath_nt.h index 230e0629d..b0c62bc39 100644 --- a/src/util/dirpath_nt.h +++ b/src/util/dirpath_nt.h @@ -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) diff --git a/src/util/get_krbrlm.c b/src/util/get_krbrlm.c index 4f69ed5ea..a95152ed0 100644 --- a/src/util/get_krbrlm.c +++ b/src/util/get_krbrlm.c @@ -28,21 +28,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 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 (KSUCCESS); + return exclude; +} + +int +afs_is_foreign_ticket_name(char *tname, char *tinst, char * tcell, 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= PR_MAXNAMELEN) { ViceLog(2, ("MapName: Name too long, using AnonymousID for %s@%s\n", diff --git a/src/viced/viced.c b/src/viced/viced.c index 0836ee9fa..53d752263 100644 --- a/src/viced/viced.c +++ b/src/viced/viced.c @@ -1074,7 +1074,8 @@ ParseArgs(int argc, char *argv[]) return -1; } } 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; @@ -1085,7 +1086,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 \n"); -- 2.39.5