From 6f5dbd110e294016f4a790269abf80843426aff0 Mon Sep 17 00:00:00 2001 From: Russ Allbery Date: Tue, 18 Dec 2007 02:20:30 +0000 Subject: [PATCH] * Apply upstream patch from the 1.5 series to allow multiple realms to be listed in the server krb.conf and hence treated as local. * Mention in README.Debian that the server is built with supergroups enabled and with the multiple local realm patch. (Closes: #453399) --- debian/README.Debian | 17 +- debian/changelog | 6 +- debian/patches/multiple-local-realms | 578 +++++++++++++++++++++++++++ debian/patches/series | 1 + 4 files changed, 600 insertions(+), 2 deletions(-) create mode 100644 debian/patches/multiple-local-realms diff --git a/debian/README.Debian b/debian/README.Debian index 5c3b44fc3..5a43dcb1a 100644 --- a/debian/README.Debian +++ b/debian/README.Debian @@ -60,6 +60,21 @@ Changes Relative to Stock OpenAFS To distinguish between an SMP and a non-SMP kernel module package, use --append_to_version; see README.modules for more information. + The OpenAFS servers have been built with --enable-supergroups, which + permits nesting of PTS groups. Be aware that the PT database created by + these packages is not compatible with servers not built with + --enable-supergroups if nested PTS groups are used. In other words, if + you need the openafs-dbserver package to interoperate with ptservers + that aren't built with this option, don't use this capability. + + The OpenAFS servers have been patched to support listing up to four + realms in /etc/openafs/server/krb.conf. Any realms listed in that file + (all on one line, space-separated) will be treated as local for + authorization decisions (in other words, the relam will be stripped off + and the unqualified principal name checked against AFS ACLs, UserList, + PTS groups, and so forth). The default OpenAFS server only supports + listing one realm in this file. + The AFS up utility is installed as afs-up, since the standard name is rather generic. @@ -159,4 +174,4 @@ PAM Authentication the openafs-kpasswd package to get the administrative utilities for managing those Kerberos accounts. - -- Russ Allbery , Sun, 18 Nov 2007 19:57:23 -0800 + -- Russ Allbery , Mon, 17 Dec 2007 18:22:35 -0800 diff --git a/debian/changelog b/debian/changelog index 5eb48ab7e..c8e625edd 100644 --- a/debian/changelog +++ b/debian/changelog @@ -7,10 +7,14 @@ openafs (1.4.6.dfsg1-1) UNRELEASED; urgency=low * Apply upstream patch to allocate vnodes from the malloc pool rather than off the stack, fixing file server problems on SPARC. Thanks to Barney Sowood for tracking down the patch. (Closes: #448380) + * Apply upstream patch from the 1.5 series to allow multiple realms to + be listed in the server krb.conf and hence treated as local. * Add more debugging and bug reporting instructions to README.Debian. + * Mention in README.Debian that the server is built with supergroups + enabled and with the multiple local realm patch. (Closes: #453399) * Update to standards version 3.7.3 (no changes required). - -- Russ Allbery Mon, 17 Dec 2007 16:42:41 -0800 + -- Russ Allbery Mon, 17 Dec 2007 18:23:26 -0800 openafs (1.4.5.dfsg1-1) unstable; urgency=low diff --git a/debian/patches/multiple-local-realms b/debian/patches/multiple-local-realms new file mode 100644 index 000000000..c2655613a --- /dev/null +++ b/debian/patches/multiple-local-realms @@ -0,0 +1,578 @@ +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. + +--- openafs.orig/src/audit/audit.c ++++ openafs/src/audit/audit.c +@@ -447,12 +447,43 @@ + } + 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, "@"); +--- openafs.orig/src/auth/userok.c ++++ openafs/src/auth/userok.c +@@ -403,7 +403,9 @@ + + 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 @@ + /* 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; +@@ -467,7 +498,6 @@ + flag = 1; + #endif + } +- + /* cell of conn doesn't match local cell or realm */ + } else { + if ((tmp = CompFindUser(adir, tname, ".", tinst, tcell))) { +--- openafs.orig/src/config/afs_sysnames.h ++++ openafs/src/config/afs_sysnames.h +@@ -286,4 +286,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_ */ +--- openafs.orig/src/ptserver/ptprocs.c ++++ openafs/src/ptserver/ptprocs.c +@@ -93,6 +93,7 @@ + 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(); +@@ -178,22 +179,9 @@ + 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)) +@@ -640,7 +628,24 @@ + 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, +@@ -2281,7 +2286,6 @@ + } + #endif /* IP_WILDCARDS */ + +- + afs_int32 + WhoIsThisWithName(acall, at, aid, aname) + struct rx_call *acall; +@@ -2309,11 +2313,12 @@ + } 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)) +@@ -2322,19 +2327,9 @@ + 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, "@"); +--- openafs.orig/src/util/afsutil_prototypes.h ++++ openafs/src/util/afsutil_prototypes.h +@@ -74,7 +74,8 @@ + + /* 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); +--- openafs.orig/src/util/dirpath.c ++++ openafs/src/util/dirpath.c +@@ -365,6 +365,8 @@ + 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 +--- openafs.orig/src/util/dirpath.hin ++++ openafs/src/util/dirpath.hin +@@ -144,6 +144,7 @@ + #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 @@ + 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 @@ + #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) +--- openafs.orig/src/util/dirpath_nt.h ++++ openafs/src/util/dirpath_nt.h +@@ -135,6 +135,7 @@ + #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 @@ + 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 @@ + #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) +--- openafs.orig/src/util/get_krbrlm.c ++++ openafs/src/util/get_krbrlm.c +@@ -26,21 +26,148 @@ + #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", +--- openafs.orig/src/viced/viced.c ++++ openafs/src/viced/viced.c +@@ -1077,7 +1077,8 @@ + 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; +@@ -1088,7 +1089,15 @@ + 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"); diff --git a/debian/patches/series b/debian/patches/series index 56433e367..3e4513d15 100644 --- a/debian/patches/series +++ b/debian/patches/series @@ -12,3 +12,4 @@ ktc-prototypes afs-man-name linux-2.6.24 alloc-vnode +multiple-local-realms -- 2.39.5