XRootD
XrdNetSecurity.cc
Go to the documentation of this file.
1 /******************************************************************************/
2 /* */
3 /* X r d N e t S e c u r i t y . c c */
4 /* */
5 /* (c) 2004 by the Board of Trustees of the Leland Stanford, Jr., University */
6 /* Produced by Andrew Hanushevsky for Stanford University under contract */
7 /* DE-AC02-76-SFO0515 with the Department of Energy */
8 /* */
9 /* This file is part of the XRootD software suite. */
10 /* */
11 /* XRootD is free software: you can redistribute it and/or modify it under */
12 /* the terms of the GNU Lesser General Public License as published by the */
13 /* Free Software Foundation, either version 3 of the License, or (at your */
14 /* option) any later version. */
15 /* */
16 /* XRootD is distributed in the hope that it will be useful, but WITHOUT */
17 /* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or */
18 /* FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public */
19 /* License for more details. */
20 /* */
21 /* You should have received a copy of the GNU Lesser General Public License */
22 /* along with XRootD in a file called COPYING.LESSER (LGPL license) and file */
23 /* COPYING (GPL license). If not, see <http://www.gnu.org/licenses/>. */
24 /* */
25 /* The copyright holder's institutional names and contributor's names may not */
26 /* be used to endorse or promote products derived from this software without */
27 /* specific prior written permission of the institution or contributor. */
28 /******************************************************************************/
29 
30 #ifndef WIN32
31 #include <netdb.h>
32 #include <cstdlib>
33 #include <strings.h>
34 #include <sys/types.h>
35 #include <sys/socket.h>
36 #include <netinet/in.h>
37 #include <arpa/inet.h>
38 #else
39 #include <cstdlib>
40 #include <sys/types.h>
41 #include <Winsock2.h>
42 #include <io.h>
43 #include "XrdSys/XrdWin32.hh"
44 #endif
45 
46 #include "XrdNet/XrdNetAddr.hh"
47 #include "XrdNet/XrdNetSecurity.hh"
48 #include "XrdNet/XrdNetUtils.hh"
49 #include "XrdSys/XrdSysTrace.hh"
50 
51 #if defined(MUSL) || defined(WIN32)
52 int innetgr(const char *netgroup, const char *host, const char *user,
53  const char *domain)
54 {
55  return 0;
56 }
57 #endif
58 
59 /******************************************************************************/
60 /* L o c a l C l a s s e s */
61 /******************************************************************************/
62 
64 {
65 public:
66 
68 char *text;
69 
70  XrdNetTextList(char *newtext) {next = 0; text = strdup(newtext);}
71  ~XrdNetTextList() {if (text) free(text);}
72 };
73 
74 /******************************************************************************/
75 /* D e f i n e s */
76 /******************************************************************************/
77 
78 #define DEBUG(x) if (eTrace) {SYSTRACE(eTrace->, 0, TraceID, 0, x)}
79 
80 /******************************************************************************/
81 /* G l o b a l s */
82 /******************************************************************************/
83 
84 const char *XrdNetSecurity::TraceID = "NetSecurity";
85 
86 /******************************************************************************/
87 /* A d d H o s t */
88 /******************************************************************************/
89 
90 void XrdNetSecurity::AddHost(char *hname)
91 {
92 
93 // If this has no asterisks, then we can add it as is. Otherwise, add it to
94 // the name pattern list.
95 //
96  if (!index(hname, '*') && addHIP(hname)) return;
97 
98 // Add it to the pattern list
99 //
100  XrdOucNList *nlp = new XrdOucNList(hname);
101  HostList.Insert(nlp);
102  chkNetLst = true;
103 
104 // Echo this back if debugging
105 //
106  DEBUG(hname <<" (" <<hname <<") added to authorized hosts.");
107 }
108 
109 /******************************************************************************/
110 /* A d d N e t G r o u p */
111 /******************************************************************************/
112 
114 {
115  XrdNetTextList *tlp = new XrdNetTextList(gname);
116 
117 // Add netgroup to list of valid ones
118 //
119  tlp->next = NetGroups;
120  NetGroups = tlp;
121  chkNetGrp = true;
122 
123 // All done
124 //
125  DEBUG(gname <<" added to authorized netgroups.");
126 }
127 
128 /******************************************************************************/
129 /* A u t h o r i z e */
130 /******************************************************************************/
131 
132 bool XrdNetSecurity::Authorize(const char *hSpec)
133 {
134  XrdNetAddr theAddr;
135 
136 // Convert the specification to a host address and validate it
137 //
138  if (theAddr.Set(hSpec, -1094)) return false;
139 
140 // Now authorize what we have
141 //
142  return Authorize(theAddr);
143 }
144 
145 /******************************************************************************/
146 
148 {
149  static const int fmtOpts = XrdNetAddr::old6Map4 | XrdNetAddr::noPort;
150  const char *hName;
151  char ipAddr[64];
152  XrdNetTextList *tlp;
153 
154 // Convert IP address to characters
155 //
156  if (!addr.Format(ipAddr, sizeof(ipAddr), XrdNetAddr::fmtAdv6, fmtOpts))
157  return false;
158 
159 // Check if we have seen this host before
160 //
161  okHMutex.Lock();
162  if (OKHosts.Find(ipAddr)) {okHMutex.UnLock(); return true;}
163 
164 // Get the hostname for this IP address
165 //
166  if (!chkNetLst && !chkNetGrp) {okHMutex.UnLock(); return false;}
167  if (!(hName = addr.Name())) hName = ipAddr;
168 
169 // Check if this host is in the the appropriate netgroup, if any
170 //
171  if ((tlp = NetGroups))
172  do {if (innetgr(tlp->text, hName, 0, 0))
173  return hostOK(hName, ipAddr, "netgroup");
174  } while ((tlp = tlp->next));
175 
176 // Plow through the specific host list to see if the host
177 //
178  if (chkNetLst && HostList.Find(hName))
179  return hostOK(hName, ipAddr, "host");
180 
181 // Host is not authorized
182 //
183  okHMutex.UnLock();
184  DEBUG(hName <<" not authorized");
185  return false;
186 }
187 
188 /******************************************************************************/
189 /* M e r g e */
190 /******************************************************************************/
191 
193 {
194  XrdOucNList *np;
195  XrdNetTextList *sp, *tp;
196 
197 // First merge in all of the host entries
198 //
199  while((np = srcp->HostList.Pop())) HostList.Replace(np);
200 
201 // Next merge the netgroup list
202 //
203  while((sp = srcp->NetGroups))
204  {tp = NetGroups; srcp->NetGroups = sp->next;
205  while(tp) if (!strcmp(tp->text, sp->text)) break;
206  else tp = tp->next;
207  if (tp) delete sp;
208  else {sp->next = NetGroups;
209  NetGroups = sp;
210  }
211  }
212 
213 // Delete the remnants of the source object
214 //
215  delete srcp;
216 }
217 
218 /******************************************************************************/
219 /* P r i v a t e M e t h o d s */
220 /******************************************************************************/
221 /******************************************************************************/
222 /* a d d H I P */
223 /******************************************************************************/
224 
225 bool XrdNetSecurity::addHIP(const char *hname)
226 {
227  static const int fmtOpts = XrdNetAddr::old6Map4 | XrdNetAddr::noPort;
228  XrdNetAddr *iP;
229  const char *eTxt;
230  char ipbuff[64];
231  int i, iN;
232 
233 // Obatin all of the addresses associated with this host
234 //
235  eTxt = XrdNetUtils::GetAddrs(hname, &iP, iN, XrdNetUtils::allIPMap, 0);
236  if (eTxt)
237  {DEBUG(hname <<"IP add to authorized hosts failed; " <<eTxt);
238  return false;
239  }
240 
241 // Add each IP address to the host hash
242 //
243  for (i = 0; i < iN; i++)
244  if (iP[i].Format(ipbuff, sizeof(ipbuff), XrdNetAddr::fmtAdv6, fmtOpts))
245  {OKHosts.Add(ipbuff, 0, 0, Hash_data_is_key);
246  DEBUG(ipbuff <<" (" <<hname <<") added to authorized hosts.");
247  }
248 
249 // return success
250 //
251  delete [] iP;
252  return true;
253 }
254 
255 /******************************************************************************/
256 /* h o s t O K */
257 /******************************************************************************/
258 
259 bool XrdNetSecurity::hostOK(const char *hname, const char *ipname,
260  const char *why)
261 {
262 
263 // Add host to valid host table and return true. Note that the okHMutex must
264 // be locked upon entry and it will be unlocked upon exit.
265 //
266  OKHosts.Add(ipname, 0, 0, Hash_data_is_key);
267  okHMutex.UnLock();
268  DEBUG(hname <<" authorized via " <<why);
269  return true;
270 }
#define DEBUG(x)
@ Hash_data_is_key
Definition: XrdOucHash.hh:52
static const int noPort
Do not add port number.
static const int old6Map4
Use deprecated IPV6 mapped format.
int Format(char *bAddr, int bLen, fmtUse fmtType=fmtAuto, int fmtOpts=0)
const char * Name(const char *eName=0, const char **eText=0)
const char * Set(const char *hSpec, int pNum=PortInSpec)
Definition: XrdNetAddr.cc:216
bool Authorize(const char *hSpec)
void AddHost(char *hname)
void AddNetGroup(char *hname)
void Merge(XrdNetSecurity *srcp)
XrdNetTextList * next
XrdNetTextList(char *newtext)
static const char * GetAddrs(const char *hSpec, XrdNetAddr *aListP[], int &aListN, AddrOpts opts=allIPMap, int pNum=PortInSpec)
Definition: XrdNetUtils.cc:239
T * Add(const char *KeyVal, T *KeyData, const int LifeTime=0, XrdOucHash_Options opt=Hash_default)
Definition: XrdOucHash.icc:61
T * Find(const char *KeyVal, time_t *KeyTime=0)
Definition: XrdOucHash.icc:160
XrdOucNList * Pop()
Definition: XrdOucNList.hh:110
void Insert(XrdOucNList *newitem)
Definition: XrdOucNList.hh:102
XrdOucNList * Find(const char *name)
Definition: XrdOucNList.hh:89
void Replace(const char *name, int nval)
Definition: XrdOucNList.cc:110