From cc4e292174f36868008d35df63df57543f033ee4 Mon Sep 17 00:00:00 2001 From: "Chas Williams (CONTRACTOR)" Date: Wed, 26 Mar 2014 10:15:10 -0400 Subject: [PATCH] ptserver: Optionally restrict anonymous access to the ptserver Currently, one could simply query from 0 to 'pts listmax' to determine all the usernames in a cell. The -restrict_anonymous option will block access to almost all of the unauthenticated RPC's. PR_NameToID is still open since aklog still needs access to this RPC. An "attack" against this RPC would have to scan a much larger key space to determine valid usernames in a cell. Change-Id: I7e475bc004f08d28d195c199804befa89f0ceb0c Reviewed-on: http://gerrit.openafs.org/10951 Tested-by: BuildBot Reviewed-by: Gergely Risko Reviewed-by: Benjamin Kaduk Reviewed-by: D Brashear --- doc/man-pages/pod8/ptserver.pod | 7 +++- src/ptserver/ptprocs.c | 63 +++++++++++++++++++++++++-------- src/ptserver/ptserver.c | 5 +++ 3 files changed, 59 insertions(+), 16 deletions(-) diff --git a/doc/man-pages/pod8/ptserver.pod b/doc/man-pages/pod8/ptserver.pod index f926bae14..7318900c7 100644 --- a/doc/man-pages/pod8/ptserver.pod +++ b/doc/man-pages/pod8/ptserver.pod @@ -12,7 +12,7 @@ ptserver S<<< [B<-database> | B<-db> >] >>> S<<< [B<-d> >] >>> S<<< [B<-groupdepth> | B<-depth> >] >>> S<<< [B<-default_access> > >] >>> - [B<-restricted>] [B<-enable_peer_stats>] + [B<-restricted>] [B<-restrict_anonymous>] [B<-enable_peer_stats>] [B<-enable_process_stats>] [B<-allow-dotted-principals>] [B<-rxbind>] S<<< [B<-auditlog> >] >>> S<<< [B<-audit-interface> (file | sysvmq)] >>> @@ -113,6 +113,11 @@ information on the flags. Run the PT Server in restricted mode. While in restricted mode, only members of the system:administrators PTS group may make any PTS changes. +=item B<-restrict_anonymous> + +Run the PT Server in restricted anonymous access mode. While in this mode, +only authenticated users will be able to access the PTS database. + =item B<-enable_peer_stats> Activates the collection of Rx statistics and allocates memory for their diff --git a/src/ptserver/ptprocs.c b/src/ptserver/ptprocs.c index d97f3347f..06fbdb30f 100644 --- a/src/ptserver/ptprocs.c +++ b/src/ptserver/ptprocs.c @@ -71,6 +71,7 @@ #include "afs/audit.h" extern int restricted; +extern int restrict_anonymous; extern struct ubik_dbase *dbase; extern int pr_noAuth; extern int prp_group_default; @@ -88,7 +89,7 @@ static afs_int32 dumpEntry(struct rx_call *call, afs_int32 apos, static afs_int32 addToGroup(struct rx_call *call, afs_int32 aid, afs_int32 gid, afs_int32 *cid); static afs_int32 nameToID(struct rx_call *call, namelist *aname, idlist *aid); -static afs_int32 idToName(struct rx_call *call, idlist *aid, namelist *aname); +static afs_int32 idToName(struct rx_call *call, idlist *aid, namelist *aname, afs_int32 *cid); static afs_int32 Delete(struct rx_call *call, afs_int32 aid, afs_int32 *cid); static afs_int32 UpdateEntry(struct rx_call *call, afs_int32 aid, char *name, struct PrUpdateEntry *uentry, afs_int32 *cid); @@ -99,8 +100,8 @@ static afs_int32 getCPS(struct rx_call *call, afs_int32 aid, prlist *alist, static afs_int32 getCPS2(struct rx_call *call, afs_int32 aid, afs_uint32 ahost, prlist *alist, afs_int32 *over, afs_int32 *cid); static afs_int32 getHostCPS(struct rx_call *call, afs_uint32 ahost, - prlist *alist, afs_int32 *over); -static afs_int32 listMax(struct rx_call *call, afs_int32 *uid, afs_int32 *gid); + prlist *alist, afs_int32 *over, afs_int32 *cid); +static afs_int32 listMax(struct rx_call *call, afs_int32 *uid, afs_int32 *gid, afs_int32 *cid); static afs_int32 setMax(struct rx_call *call, afs_int32 aid, afs_int32 gflag, afs_int32 *cid); static afs_int32 listEntry(struct rx_call *call, afs_int32 aid, @@ -373,6 +374,8 @@ whereIsIt(struct rx_call *call, afs_int32 aid, afs_int32 *apos, afs_int32 *cid) code = WhoIsThis(call, tt, cid); if (code) ABORT_WITH(tt, PRPERM); + if (!pr_noAuth && restrict_anonymous && *cid == ANONYMOUSID) + ABORT_WITH(tt, PRPERM); temp = FindByID(tt, aid); if (!temp) @@ -609,15 +612,16 @@ afs_int32 SPR_IDToName(struct rx_call *call, idlist *aid, namelist *aname) { afs_int32 code; + afs_int32 cid = ANONYMOUSID; - code = idToName(call, aid, aname); + code = idToName(call, aid, aname, &cid); osi_auditU(call, PTS_IdToNmEvent, code, AUD_END); ViceLog(125, ("PTS_IDToName: code %d\n", code)); return code; } static afs_int32 -idToName(struct rx_call *call, idlist *aid, namelist *aname) +idToName(struct rx_call *call, idlist *aid, namelist *aname, afs_int32 *cid) { afs_int32 code; struct ubik_trans *tt; @@ -644,6 +648,12 @@ idToName(struct rx_call *call, idlist *aid, namelist *aname) if (code) return code; + code = WhoIsThis(call, tt, cid); + if (code) + ABORT_WITH(tt, PRPERM); + if (!pr_noAuth && restrict_anonymous && *cid == ANONYMOUSID) + ABORT_WITH(tt, PRPERM); + for (i = 0; i < aid->idlist_len; i++) { code = IDToName(tt, aid->idlist_val[i], aname->namelist_val[i]); if (code != PRSUCCESS) @@ -1088,6 +1098,12 @@ getCPS(struct rx_call *call, afs_int32 aid, prlist *alist, afs_int32 *over, if (code) return code; + code = WhoIsThis(call, tt, cid); + if (code) + ABORT_WITH(tt, PRPERM); + if (!pr_noAuth && restrict_anonymous && *cid == ANONYMOUSID) + ABORT_WITH(tt, PRPERM); + temp = FindByID(tt, aid); if (!temp) ABORT_WITH(tt, PRNOENT); @@ -1095,9 +1111,7 @@ getCPS(struct rx_call *call, afs_int32 aid, prlist *alist, afs_int32 *over, if (code) ABORT_WITH(tt, code); - /* afs does authenticate now */ - code = WhoIsThis(call, tt, cid); - if (code || !AccessOK(tt, *cid, &tentry, PRP_MEMBER_MEM, PRP_MEMBER_ANY)) + if (!AccessOK(tt, *cid, &tentry, PRP_MEMBER_MEM, PRP_MEMBER_ANY)) ABORT_WITH(tt, PRPERM); code = GetList(tt, &tentry, alist, 1); @@ -1204,8 +1218,9 @@ SPR_GetHostCPS(struct rx_call *call, afs_int32 ahost, prlist *alist, afs_int32 *over) { afs_int32 code; + afs_int32 cid = ANONYMOUSID; - code = getHostCPS(call, ahost, alist, over); + code = getHostCPS(call, ahost, alist, over, &cid); osi_auditU(call, PTS_GetHCPSEvent, code, AUD_HOST, htonl(ahost), AUD_END); ViceLog(125, ("PTS_GetHostCPS: code %d ahost %d\n", code, ahost)); return code; @@ -1213,7 +1228,7 @@ SPR_GetHostCPS(struct rx_call *call, afs_int32 ahost, prlist *alist, afs_int32 getHostCPS(struct rx_call *call, afs_uint32 ahost, prlist *alist, - afs_int32 *over) + afs_int32 *over, afs_int32 *cid) { afs_int32 code, temp; struct ubik_trans *tt; @@ -1231,6 +1246,12 @@ getHostCPS(struct rx_call *call, afs_uint32 ahost, prlist *alist, if (code) return code; + code = WhoIsThis(call, tt, cid); + if (code) + ABORT_WITH(tt, PRPERM); + if (!pr_noAuth && restrict_anonymous && *cid == ANONYMOUSID) + ABORT_WITH(tt, PRPERM); + code = NameToID(tt, afs_inet_ntoa_r(iaddr.s_addr, hoststr), &hostid); if (code == PRSUCCESS && hostid != 0) { temp = FindByID(tt, hostid); @@ -1259,15 +1280,16 @@ afs_int32 SPR_ListMax(struct rx_call *call, afs_int32 *uid, afs_int32 *gid) { afs_int32 code; + afs_int32 cid = ANONYMOUSID; - code = listMax(call, uid, gid); + code = listMax(call, uid, gid, &cid); osi_auditU(call, PTS_LstMaxEvent, code, AUD_END); ViceLog(125, ("PTS_ListMax: code %d\n", code)); return code; } afs_int32 -listMax(struct rx_call *call, afs_int32 *uid, afs_int32 *gid) +listMax(struct rx_call *call, afs_int32 *uid, afs_int32 *gid, afs_int32 *cid) { afs_int32 code; struct ubik_trans *tt; @@ -1276,6 +1298,12 @@ listMax(struct rx_call *call, afs_int32 *uid, afs_int32 *gid) if (code) return code; + code = WhoIsThis(call, tt, cid); + if (code) + ABORT_WITH(tt, PRPERM); + if (!pr_noAuth && restrict_anonymous && *cid == ANONYMOUSID) + ABORT_WITH(tt, PRPERM); + code = GetMax(tt, uid, gid); if (code != PRSUCCESS) ABORT_WITH(tt, code); @@ -1355,6 +1383,8 @@ listEntry(struct rx_call *call, afs_int32 aid, struct prcheckentry *aentry, code = WhoIsThis(call, tt, cid); if (code) ABORT_WITH(tt, PRPERM); + if (!pr_noAuth && restrict_anonymous && *cid == ANONYMOUSID) + ABORT_WITH(tt, PRPERM); temp = FindByID(tt, aid); if (!temp) ABORT_WITH(tt, PRNOENT); @@ -1739,12 +1769,15 @@ listSuperGroups(struct rx_call *call, afs_int32 aid, prlist *alist, if (code) return code; - code = ubik_SetLock(tt, 1, 1, LOCKREAD); - if (code) - ABORT_WITH(tt, code); code = WhoIsThis(call, tt, cid); if (code) ABORT_WITH(tt, PRPERM); + if (!pr_noAuth && restrict_anonymous && *cid == ANONYMOUSID) + ABORT_WITH(tt, PRPERM); + + code = ubik_SetLock(tt, 1, 1, LOCKREAD); + if (code) + ABORT_WITH(tt, code); temp = FindByID(tt, aid); if (!temp) diff --git a/src/ptserver/ptserver.c b/src/ptserver/ptserver.c index 8df4e3a04..248b66317 100644 --- a/src/ptserver/ptserver.c +++ b/src/ptserver/ptserver.c @@ -147,6 +147,7 @@ extern afs_int32 depthsg; #endif int restricted = 0; +int restrict_anonymous = 0; int rxMaxMTU = -1; int rxBind = 0; int rxkadDisableDotCheck = 0; @@ -214,6 +215,7 @@ enum optionsList { OPT_access, OPT_groupdepth, OPT_restricted, + OPT_restrict_anonymous, OPT_auditlog, OPT_auditiface, OPT_config, @@ -316,6 +318,8 @@ main(int argc, char **argv) #endif cmd_AddParmAtOffset(opts, OPT_restricted, "-restricted", CMD_FLAG, CMD_OPTIONAL, "enable restricted mode"); + cmd_AddParmAtOffset(opts, OPT_restrict_anonymous, "-restrict_anonymous", + CMD_FLAG, CMD_OPTIONAL, "enable restricted anonymous mode"); /* general server options */ cmd_AddParmAtOffset(opts, OPT_auditlog, "-auditlog", CMD_SINGLE, @@ -376,6 +380,7 @@ main(int argc, char **argv) #endif cmd_OptionAsFlag(opts, OPT_restricted, &restricted); + cmd_OptionAsFlag(opts, OPT_restrict_anonymous, &restrict_anonymous); /* general server options */ cmd_OptionAsString(opts, OPT_auditlog, &auditFileName); -- 2.39.5