/******************************************************************************/
/* */
/* X r d N e t S e c u r i t y . c c */
/* */
/* (c) 2004 by the Board of Trustees of the Leland Stanford, Jr., University */
/* Produced by Andrew Hanushevsky for Stanford University under contract */
/* DE-AC02-76-SFO0515 with the Department of Energy */
/* */
/* This file is part of the XRootD software suite. */
/* */
/* XRootD is free software: you can redistribute it and/or modify it under */
/* the terms of the GNU Lesser General Public License as published by the */
/* Free Software Foundation, either version 3 of the License, or (at your */
/* option) any later version. */
/* */
/* XRootD is distributed in the hope that it will be useful, but WITHOUT */
/* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or */
/* FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public */
/* License for more details. */
/* */
/* You should have received a copy of the GNU Lesser General Public License */
/* along with XRootD in a file called COPYING.LESSER (LGPL license) and file */
/* COPYING (GPL license). If not, see . */
/* */
/* The copyright holder's institutional names and contributor's names may not */
/* be used to endorse or promote products derived from this software without */
/* specific prior written permission of the institution or contributor. */
/******************************************************************************/
#ifndef WIN32
#include
#include
#include
#include
#include
#include
#include
#else
#include
#include
#include
#include
int innetgr(const char *netgroup, const char *host, const char *user,
const char *domain)
{
return 0;
}
#include "XrdSys/XrdWin32.hh"
#endif
#include "XrdNet/XrdNetAddr.hh"
#include "XrdNet/XrdNetSecurity.hh"
#include "XrdNet/XrdNetUtils.hh"
#include "XrdOuc/XrdOucTrace.hh"
/******************************************************************************/
/* L o c a l C l a s s e s */
/******************************************************************************/
class XrdNetTextList
{
public:
XrdNetTextList *next;
char *text;
XrdNetTextList(char *newtext) {next = 0; text = strdup(newtext);}
~XrdNetTextList() {if (text) free(text);}
};
/******************************************************************************/
/* D e f i n e s */
/******************************************************************************/
#define DEBUG(x) if (eTrace) {eTrace->Beg(TraceID); cerr <End();}
/******************************************************************************/
/* G l o b a l s */
/******************************************************************************/
const char *XrdNetSecurity::TraceID = "NetSecurity";
/******************************************************************************/
/* A d d H o s t */
/******************************************************************************/
void XrdNetSecurity::AddHost(char *hname)
{
// If this has no asterisks, then we can add it as is. Otherwise, add it to
// the name pattern list.
//
if (!index(hname, '*') && addHIP(hname)) return;
// Add it to the pattern list
//
XrdOucNList *nlp = new XrdOucNList(hname);
HostList.Insert(nlp);
chkNetLst = true;
// Echo this back if debugging
//
DEBUG(hname <<" (" <next = NetGroups;
NetGroups = tlp;
chkNetGrp = true;
// All done
//
DEBUG(gname <<" added to authorized netgroups.");
}
/******************************************************************************/
/* A u t h o r i z e */
/******************************************************************************/
bool XrdNetSecurity::Authorize(const char *hSpec)
{
XrdNetAddr theAddr;
// Convert the specification to a host address and validate it
//
if (theAddr.Set(hSpec, -1094)) return false;
// Now authorize what we have
//
return Authorize(theAddr);
}
/******************************************************************************/
bool XrdNetSecurity::Authorize(XrdNetAddr &addr)
{
static const int fmtOpts = XrdNetAddr::old6Map4 | XrdNetAddr::noPort;
const char *hName;
char ipAddr[64];
XrdNetTextList *tlp;
// Convert IP address to characters
//
if (!addr.Format(ipAddr, sizeof(ipAddr), XrdNetAddr::fmtAdv6, fmtOpts))
return false;
// Check if we have seen this host before
//
okHMutex.Lock();
if (OKHosts.Find(ipAddr)) {okHMutex.UnLock(); return true;}
// Get the hostname for this IP address
//
if (!chkNetLst && !chkNetGrp) {okHMutex.UnLock(); return false;}
if (!(hName = addr.Name())) hName = ipAddr;
// Check if this host is in the the appropriate netgroup, if any
//
if ((tlp = NetGroups))
do {if (innetgr(tlp->text, hName, 0, 0))
return hostOK(hName, ipAddr, "netgroup");
} while ((tlp = tlp->next));
// Plow through the specific host list to see if the host
//
if (chkNetLst && HostList.Find(hName))
return hostOK(hName, ipAddr, "host");
// Host is not authorized
//
okHMutex.UnLock();
DEBUG(hName <<" not authorized");
return false;
}
/******************************************************************************/
/* M e r g e */
/******************************************************************************/
void XrdNetSecurity::Merge(XrdNetSecurity *srcp)
{
XrdOucNList *np;
XrdNetTextList *sp, *tp;
// First merge in all of the host entries
//
while((np = srcp->HostList.Pop())) HostList.Replace(np);
// Next merge the netgroup list
//
while((sp = srcp->NetGroups))
{tp = NetGroups; srcp->NetGroups = sp->next;
while(tp) if (!strcmp(tp->text, sp->text)) break;
else tp = tp->next;
if (tp) delete sp;
else {sp->next = NetGroups;
NetGroups = sp;
}
}
// Delete the remnants of the source object
//
delete srcp;
}
/******************************************************************************/
/* P r i v a t e M e t h o d s */
/******************************************************************************/
/******************************************************************************/
/* a d d H I P */
/******************************************************************************/
bool XrdNetSecurity::addHIP(const char *hname)
{
static const int fmtOpts = XrdNetAddr::old6Map4 | XrdNetAddr::noPort;
XrdNetAddr *iP;
const char *eTxt;
char ipbuff[64];
int i, iN;
// Obatin all of the addresses associated with this host
//
eTxt = XrdNetUtils::GetAddrs(hname, &iP, iN, XrdNetUtils::allIPMap, 0);
if (eTxt)
{DEBUG(hname <<"IP add to authorized hosts failed; " <