From 544dedb6eddd353094a8c7d9b30d76b80f6d2a87 Mon Sep 17 00:00:00 2001 From: Jeffrey Altman Date: Thu, 15 Dec 2005 05:51:24 +0000 Subject: [PATCH] multiple-local-realms-20051208 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 --- src/audit/audit.c | 41 +++++++-- src/auth/userok.c | 44 ++++++++-- src/config/afs_sysnames.h | 2 + src/libafsauthent/afsauthent.def | 6 +- src/ptserver/ptprocs.c | 38 ++------- src/util/afsutil_prototypes.h | 3 +- src/util/dirpath.c | 2 + 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, 260 insertions(+), 62 deletions(-) diff --git a/src/audit/audit.c b/src/audit/audit.c index aeea18567..7fe3f9a79 100644 --- a/src/audit/audit.c +++ b/src/audit/audit.c @@ -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= sizeof(vname)) goto done; strcat(vname, "@"); diff --git a/src/auth/userok.c b/src/auth/userok.c index 09da2e070..b37385f0a 100644 --- a/src/auth/userok.c +++ b/src/auth/userok.c @@ -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"); 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))) { diff --git a/src/config/afs_sysnames.h b/src/config/afs_sysnames.h index b54fc4fef..94c5076b4 100644 --- a/src/config/afs_sysnames.h +++ b/src/config/afs_sysnames.h @@ -263,4 +263,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/libafsauthent/afsauthent.def b/src/libafsauthent/afsauthent.def index a82298592..86f2437e3 100644 --- a/src/libafsauthent/afsauthent.def +++ b/src/libafsauthent/afsauthent.def @@ -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 diff --git a/src/ptserver/ptprocs.c b/src/ptserver/ptprocs.c index cb006e6ea..fd031b97c 100644 --- a/src/ptserver/ptprocs.c +++ b/src/ptserver/ptprocs.c @@ -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, "@"); diff --git a/src/util/afsutil_prototypes.h b/src/util/afsutil_prototypes.h index fbfc35f40..a3151fc25 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 *tcell, char *tname, char *tinst, 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 82e89b70c..ff856f952 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_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 0c6769a12..b707954bd 100644 --- a/src/util/get_krbrlm.c +++ b/src/util/get_krbrlm.c @@ -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= 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 9d34351b2..517ccd5fa 100644 --- a/src/viced/viced.c +++ b/src/viced/viced.c @@ -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 \n"); -- 2.39.5