XRootD
XrdSecgsiGMAPFunDN.cc
Go to the documentation of this file.
1 /******************************************************************************/
2 /* */
3 /* X r d S e c g s i G M A P F u n D N . c c */
4 /* */
5 /* (c) 2011, G. Ganis / CERN */
6 /* */
7 /* This file is part of the XRootD software suite. */
8 /* */
9 /* XRootD is free software: you can redistribute it and/or modify it under */
10 /* the terms of the GNU Lesser General Public License as published by the */
11 /* Free Software Foundation, either version 3 of the License, or (at your */
12 /* option) any later version. */
13 /* */
14 /* XRootD is distributed in the hope that it will be useful, but WITHOUT */
15 /* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or */
16 /* FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public */
17 /* License for more details. */
18 /* */
19 /* You should have received a copy of the GNU Lesser General Public License */
20 /* along with XRootD in a file called COPYING.LESSER (LGPL license) and file */
21 /* COPYING (GPL license). If not, see <http://www.gnu.org/licenses/>. */
22 /* */
23 /* The copyright holder's institutional names and contributor's names may not */
24 /* be used to endorse or promote products derived from this software without */
25 /* specific prior written permission of the institution or contributor. */
26 /* */
27 /******************************************************************************/
28 
29 /* ************************************************************************** */
30 /* */
31 /* GMAP function implementation extracting info from the DN */
32 /* */
33 /* ************************************************************************** */
34 
35 #include <cstdio>
36 #include <cstdlib>
37 #include <cstring>
38 #include <cerrno>
39 
40 #include "XrdVersion.hh"
41 
42 #include "XrdOuc/XrdOucHash.hh"
43 #include "XrdOuc/XrdOucString.hh"
44 #include "XrdOuc/XrdOucTrace.hh"
45 #include "XrdSys/XrdSysError.hh"
46 #include "XrdSys/XrdSysLogger.hh"
47 
48 static XrdSysError dnDest(0, "gmapdn_");
50 static XrdOucTrace *dnTrace = 0;
51 
52 #define TRACE_Authen 0x0002
53 #define EPNAME(x) static const char *epname = x;
54 #define PRINT(y) {if (dnTrace) {dnTrace->Beg(epname); std::cerr <<y; dnTrace->End();}}
55 #define DEBUG(y) if (dnTrace && (dnTrace->What & TRACE_Authen)) PRINT(y)
56 
57 
58 /******************************************************************************/
59 /* V e r s i o n I n f o r m a t i o n */
60 /******************************************************************************/
61 
63 
64 /******************************************************************************/
65 /* G l o b a l s & S t a t i c s */
66 /******************************************************************************/
67 
69  kBegins = 1,
70  kEnds = 2,
71  kContains = 4
72  };
73 
75 {
76 public:
77  XrdSecgsiMapEntry_t(const char *v, const char *u, int t) : val(v), user(u), type(t) { }
78 
81  int type;
82 };
83 
85 
86 /******************************************************************************/
87 /* F u n c t i o n s & M e t h o d s */
88 /******************************************************************************/
89 
90 //__________________________________________________________________________
91 static int FindMatchingCondition(const char *, XrdSecgsiMapEntry_t *mc, void *xmp)
92 {
93  // Print content of entry 'ui' and go to next
94 
96 
97  bool match = 0;
98  if (mc && mpe) {
99  if (mc->type == kContains) {
100  if (mpe->val.find(mc->val) != STR_NPOS) match = 1;
101  } else if (mc->type == kBegins) {
102  if (mpe->val.beginswith(mc->val)) match = 1;
103  } else if (mc->type == kEnds) {
104  if (mpe->val.endswith(mc->val)) match = 1;
105  } else {
106  if (mpe->val.matches(mc->val.c_str())) match = 1;
107  }
108  if (match) mpe->user = mc->user;
109  }
110 
111  // We stop if matched, otherwise we continue
112  return (match) ? 1 : 0;
113 }
114 
115 
116 int XrdSecgsiGMAPInit(const char *cfg);
117 
118 //
119 // Main function
120 //
121 extern "C"
122 {
123 char *XrdSecgsiGMAPFun(const char *dn, int now)
124 {
125  // Implementation of XrdSecgsiGMAPFun extracting the information from the
126  // distinguished name 'dn'
127  EPNAME("GMAPFunDN");
128 
129  // Init the relevant fields (only once)
130  if (now <= 0) {
131  if (XrdSecgsiGMAPInit(dn) != 0)
132  return (char *)-1;
133  return (char *)0;
134  }
135 
136  // Output
137  char *name = 0;
138 
139  XrdSecgsiMapEntry_t *mc = 0;
140  // Try the full match first
141  if ((mc = gMappings.Find(dn))) {
142  // Get the associated user
143  name = new char[mc->val.length() + 1];
144  strcpy(name, mc->val.c_str());
145  } else {
146  // Else scan the available mappings
147  mc = new XrdSecgsiMapEntry_t(dn, "", kFull);
148  gMappings.Apply(FindMatchingCondition, (void *)mc);
149  if (mc->user.length() > 0) {
150  name = new char[mc->user.length() + 1];
151  strcpy(name, mc->user.c_str());
152  }
153  }
154  if (name) {
155  DEBUG("mapping DN '"<<dn<<"' to '"<<name<<"'");
156  } else {
157  DEBUG("no valid match found for DN '"<<dn<<"'");
158  }
159 
160  // Done
161  return name;
162 }}
163 
164 //
165 // Init the relevant parameters from a dedicated config file
166 //
167 int XrdSecgsiGMAPInit(const char *parms)
168 {
169  // Initialize the relevant parameters
170  // parms = "[cfg]|[d|dbg|debug]"
171  // The config file 'cfg' can also be defined by XRDGSIGMAPDNCF.
172  // The flag 'd|dbg|debug' enables some verbosity.
173  // Return 0 on success, -1 otherwise
174  EPNAME("GMAPInitDN");
175 
176  bool debug = 0;
177  XrdOucString pps(parms), p, cfg;
178  int from = 0;
179  while ((from = pps.tokenize(p, from, '|')) != -1) {
180  if (p.length() > 0) {
181  if (p == "d" || p == "dbg" || p == "debug") {
182  debug = 1;
183  } else {
184  cfg = p;
185  }
186  }
187  }
188  // Initiate error logging and tracing
190  dnTrace = new XrdOucTrace(&dnDest);
191  if (debug) dnTrace->What |= TRACE_Authen;
192 
193  if (cfg.length() <= 0) cfg = getenv("XRDGSIGMAPDNCF");
194  if (cfg.length() <= 0) {
195  PRINT("ERROR: undefined config file path");
196  return -1;
197  }
198 
199  FILE *fcf = fopen(cfg.c_str(), "r");
200  if (fcf) {
201  char l[4096], val[4096], usr[256];
202  while (fgets(l, sizeof(l), fcf)) {
203  int len = strlen(l);
204  if (len < 2) continue;
205  if (l[0] == '#') continue;
206  if (l[len-1] == '\n') l[len-1] = '\0';
207  if (sscanf(l, "%4095s %255s", val, usr) >= 2) {
208  XrdOucString stype = "matching";
209  char *p = &val[0];
210  int type = kFull;
211  if (val[0] == '^') {
212  // Starts-with
213  type = kBegins;
214  p = &val[1];
215  stype = "beginning with";
216  } else {
217  int vlen = strlen(val);
218  if (val[vlen-1] == '$') {
219  // Ends-with
220  type = kEnds;
221  val[vlen-1] = '\0';
222  stype = "ending with";
223  } else if (val[vlen-1] == '+') {
224  // Contains
225  type = kContains;
226  val[vlen-1] = '\0';
227  stype = "containing";
228  }
229  }
230  // Register
231  gMappings.Add(p, new XrdSecgsiMapEntry_t(p, usr, type));
232  //
233  DEBUG("mapping DNs "<<stype<<" '"<<p<<"' to '"<<usr<<"'");
234  }
235  }
236  fclose(fcf);
237  } else {
238  PRINT("ERROR: config file '"<<cfg<<"' could not be open (errno: "<<errno<<")");
239  return -1;
240  }
241  // Done
242  return 0;
243 }
#define STR_NPOS
int fclose(FILE *stream)
#define fopen(a, b)
Definition: XrdPosix.hh:49
#define PRINT(y)
#define TRACE_Authen
#define EPNAME(x)
static XrdSysError dnDest(0, "gmapdn_")
char * XrdSecgsiGMAPFun(const char *dn, int now)
static int FindMatchingCondition(const char *, XrdSecgsiMapEntry_t *mc, void *xmp)
XrdSecgsi_Match
@ kBegins
@ kContains
XrdVERSIONINFO(XrdSecgsiGMAPFun, secgsigmap)
int XrdSecgsiGMAPInit(const char *cfg)
static XrdOucHash< XrdSecgsiMapEntry_t > gMappings
static XrdSysLogger dnLogger
#define DEBUG(y)
static XrdOucTrace * dnTrace
const char * c_str() const
bool endswith(char c)
bool beginswith(char c)
int matches(const char *s, char wch=' *')
int find(const char c, int start=0, bool forward=1)
int length() const
XrdSecgsiMapEntry_t(const char *v, const char *u, int t)
XrdSysLogger * logger(XrdSysLogger *lp=0)
Definition: XrdSysError.hh:141