XRootD
Loading...
Searching...
No Matches
XrdSecgsiAuthzFunVO.cc
Go to the documentation of this file.
1/******************************************************************************/
2/* */
3/* X r d S e c g s i A u t h z F u n V O . c c */
4/* */
5/* (c) 2011 by the Board of Trustees of the Leland Stanford, Jr., University */
6/* All Rights Reserved */
7/* Produced by Andrew Hanushevsky for Stanford University under contract */
8/* DE-AC02-76-SFO0515 with the Department of Energy */
9/* */
10/* This file is part of the XRootD software suite. */
11/* */
12/* XRootD is free software: you can redistribute it and/or modify it under */
13/* the terms of the GNU Lesser General Public License as published by the */
14/* Free Software Foundation, either version 3 of the License, or (at your */
15/* option) any later version. */
16/* */
17/* XRootD is distributed in the hope that it will be useful, but WITHOUT */
18/* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or */
19/* FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public */
20/* License for more details. */
21/* */
22/* You should have received a copy of the GNU Lesser General Public License */
23/* along with XRootD in a file called COPYING.LESSER (LGPL license) and file */
24/* COPYING (GPL license). If not, see <http://www.gnu.org/licenses/>. */
25/* */
26/* The copyright holder's institutional names and contributor's names may not */
27/* be used to endorse or promote products derived from this software without */
28/* specific prior written permission of the institution or contributor. */
29/******************************************************************************/
30
31/* Trivial AuthzKey/Func(), propogates the VO as a unix user and/or group.
32
331. To be used with gsi parametrized like:
34
35 sec.protocol /opt/xrootd/lib/x86_64_linux_26 gsi \
36 -certdir:/etc/grid-security/certificates \
37 -cert:/etc/grid-security/xrd/xrdcert.pem \
38 -key:/etc/grid-security/xrd/xrdkey.pem -crl:3 \
39 -authzfun:libXrdAuthzVO.so -authzfunparms:<parms> \
40 -gmapopt:10 -gmapto:0
41
422. The optional authzfunparms is formatted as a CGI string with one or more
43 of the following key-value pairs:
44
45 debug=1
46 valido=<vlist>
47 vo2grp=<gspec>
48 vo2usr=<uspec>
49
50 Where: debug - turns debugging on.
51 vlist - specifies a comma-separated list of vo names that are
52 acceptable. If not specified, all vo's are accepted.
53 Otherwise, failure is returned if the the vo is not in
54 the list of vo's.
55 gspec - specifies how the vo is to be inserted into a group name.
56 Specify a printf-like format string with a single %s. This
57 is where the vo name is inserted. So, "%s" simply makes the
58 group name the vo name.
59 uspec - specifies how the vo is to be inserted into a user name.
60 The same rules apply as for gspec. If uspec is not specified
61 then the name comes from distinguished name in the
62 certificate (i.e. text after '/CN=') with spaces turned
63 into underscores and the vo is not used. If uspec is
64 specified as a single asterisk (*) then the name field is
65 not touched and is as set by the gsi module.
66*/
67
68#include <cstdio>
69#include <cstdlib>
70#include <cstring>
71#include <unistd.h>
72
73#include "XrdVersion.hh"
74
78#include "XrdOuc/XrdOucEnv.hh"
79#include "XrdOuc/XrdOucLock.hh"
80
81/******************************************************************************/
82/* V e r s i o n I n f o r m a t i o n */
83/******************************************************************************/
84
86
88
90
91/******************************************************************************/
92/* E x t e r n a l F u n c t i o n s */
93/******************************************************************************/
94
95// The following functions are called by the authz plug-in driver.
96//
97extern "C"
98{
99 int XrdSecgsiAuthzInit(const char *cfg);
100 int XrdSecgsiAuthzFun(XrdSecEntity &entity);
101 int XrdSecgsiAuthzKey(XrdSecEntity &entity, char **key);
102}
103
104/******************************************************************************/
105/* G l o b a l V a r i a b l e s */
106/******************************************************************************/
107
108namespace
109{
110 const int g_certificate_format = 1;
111 const int g_maxvolen = 255;
112 static char *g_valido = 0;
113 static char *g_vo2grp = 0;
114 static char *g_vo2usr = 0;
115 static int g_debug = 0;
116 static int g_cn2usr = 1;
117}
118
119/******************************************************************************/
120/* L o c a l D e f i n e s */
121/******************************************************************************/
122
123#undef PRINT
124#define PRINT(y) if (g_debug) {std::cerr << y << "\n";}
125#undef PROUT
126#define PROUT(_x_) \
127 std::cerr <<inf_pfx <<"entity." #_x_ "='" <<(entity._x_ ? entity._x_ : "") <<"'.\n"
128
129/******************************************************************************/
130/* X r d S e c g s i A u t h z F u n */
131/******************************************************************************/
132
133/* Replace the group list and/or user name with the VO name if the VO is ours.
134
135 Return <0 on fatal failure
136 >0 error (this will still log the guy in, it seems)
137 0 success, local username in entity.name
138*/
139
141{
142 static const char* inf_pfx = "INFO in AuthzFun: ";
143 static XrdSysMutex Mutex;
144 const char *vtxt = "", *etxt = 0;
145 char vbuff[(g_maxvolen+1)*2];
146 int i, n;
147
148// We must have a vo, it must be shorter than 255 bytes, and it must be in our
149// vo list of we have one
150//
151 if (!entity.vorg) etxt = "missing";
152 else if ((n = strlen(entity.vorg)) > g_maxvolen) etxt = "too long";
153 else if (g_valido)
154 {*vbuff = ',';
155 strcpy(vbuff+1, entity.vorg);
156 if (!strstr(g_valido, vbuff))
157 {vtxt = entity.vorg; etxt = " not allowed";}
158 }
159
160// Check if we passed the tests
161//
162 if (etxt)
163 {std::cerr <<"AuthzVO: Invalid cert; vo " <<vtxt <<etxt <<std::endl;
164 return -1;
165 }
166
167// Format group name if so wanted
168//
169 if (g_vo2grp)
170 {snprintf(vbuff, sizeof(vbuff), g_vo2grp, entity.vorg);
171 if (entity.grps) free(entity.grps);
172 entity.grps = strdup(vbuff);
173 }
174
175// Format user name if so wanted
176//
177 if (g_vo2usr)
178 {snprintf(vbuff, sizeof(vbuff), g_vo2usr, entity.vorg);
179 if (entity.name) free(entity.name);
180 entity.name = strdup(vbuff);
181 } else if (g_cn2usr && entity.name && (vtxt=strstr(entity.name,"/CN=")))
182 {char *cP = vbuff;
183 strncpy(vbuff, vtxt+4, g_maxvolen); vbuff[n] = 0;
184 while(*cP) {if (*cP == ' ') *cP = '_'; cP++;}
185 for (i = n-1; i >= 0; i--) {if (*cP == '_') *cP = 0;}
186 if (*vbuff)
187 {if (entity.name) free(entity.name);
188 entity.name = strdup(vbuff);
189 }
190 }
191
192// If debugging then print information. However, get a global mutex to keep
193// from inter-leaving these lines with other threads, as much as possible.
194//
195 if (g_debug)
196 {XrdOucLock lock(&Mutex);
197 PROUT(name); PROUT(host); PROUT(grps); PROUT(vorg); PROUT(role);
198 }
199
200// All done
201//
202 return 0;
203}
204
205/******************************************************************************/
206/* X r d S e c g s i A u t h z K e y */
207/******************************************************************************/
208
209int XrdSecgsiAuthzKey(XrdSecEntity &entity, char **key)
210{
211 // Return key by which entity.creds will be hashed.
212 // For now return entity.creds itself.
213 // The plan is to use DN + VO endorsements in the future.
214
215 static const char* err_pfx = "ERR in AuthzKey: ";
216 static const char* inf_pfx = "INFO in AuthzKey: ";
217
218 // Must have got something
219 if (!key) {
220 PRINT(err_pfx << "'key' is not defined!");
221 return -1;
222 }
223
224 PRINT(inf_pfx << "Returning creds of len " << entity.credslen << " as key.");
225
226 // Set the key
227 *key = new char[entity.credslen + 1];
228 strcpy(*key, entity.creds);
229
230 return entity.credslen;
231}
232
233/******************************************************************************/
234/* X r d S e c g s i A u t h z I n i t */
235/******************************************************************************/
236
237int XrdSecgsiAuthzInit(const char *cfg)
238{
239 // Return:
240 // -1 on falure
241 // 0 to get credentials in raw form
242 // 1 to get credentials in PEM base64 encoded form
243
244 static const char* inf_pfx = "INFO in AuthzInit: ";
245 XrdOucEnv *envP;
246 char cfgbuff[2048], *sP;
247 int i;
248
249// The configuration string may mistakingly include other parms following
250// the auzparms. So, trim the string.
251//
252 if (cfg)
253 {i = strlen(cfg);
254 if (i >= (int)sizeof(cfgbuff)) i = sizeof(cfgbuff)-1;
255 memcpy(cfgbuff, cfg, i);
256 cfgbuff[i] = 0;
257 if ((sP = index(cfgbuff, ' '))) *sP = 0;
258 }
259 if (!cfg || !(*cfg)) return g_certificate_format;
260
261// Parse the config line (it's in cgi format)
262//
263 envP = new XrdOucEnv(cfgbuff);
264
265// Set debug value
266//
267 if ((sP = envP->Get("debug")) && *sP == '1') g_debug = 1;
268
269// Get the mapping strings
270//
271 if ((g_vo2grp = envP->Get("vo2grp"))) g_vo2grp = strdup(g_vo2grp);
272 if ((g_vo2usr = envP->Get("vo2usr")))
273 {g_cn2usr = 0;
274 g_vo2usr = (!strcmp(g_vo2usr, "*") ? 0 : strdup(g_vo2usr));
275 }
276
277// Now process the valid vo's
278//
279 if ((sP = envP->Get("valido")))
280 {i = strlen(sP);
281 g_valido = (char *)malloc(i+2);
282 *g_valido = ',';
283 strcpy(g_valido+1, sP);
284 }
285
286// All done with environment
287//
288 delete envP;
289
290// All done.
291//
292 PRINT(inf_pfx <<"cfg='"<< (cfg ? cfg : "null") << "'.");
293 return g_certificate_format;
294}
int XrdSecgsiAuthzKey(XrdSecEntity &entity, char **key)
int XrdSecgsiAuthzFun(XrdSecEntity &entity)
int XrdSecgsiAuthzInit(const char *cfg)
#define PRINT(y)
XrdVERSIONINFO(XrdSecgsiAuthzFun, secgsiauthz)
#define PROUT(_x_)
int XrdSecgsiAuthzKey(XrdSecEntity &entity, char **key)
int XrdSecgsiAuthzFun(XrdSecEntity &entity)
int XrdSecgsiAuthzInit(const char *cfg)
char * Get(const char *varname)
Definition XrdOucEnv.hh:69
char * vorg
Entity's virtual organization(s)
int credslen
Length of the 'creds' data.
char * creds
Raw entity credentials or cert.
char * grps
Entity's group name(s)
char * name
Entity's name.