00001 #include "XrdTokenAuthzOfs.hh"
00002 #include "XrdOfs/XrdOfsTrace.hh"
00003 #include "XrdSys/XrdSysError.hh"
00004 #include "XrdOuc/XrdOucTrace.hh"
00005 #include "XrdOss/XrdOssApi.hh"
00006 #include "XrdOuc/XrdOucString.hh"
00007 #define WITHTHREADS
00008 #include "TTokenAuthz.h"
00009 #include <sys/time.h>
00010 #include <stdarg.h>
00011
00012
00013 #define ALIEN_BACKDOOR
00014
00015 extern XrdTokenAuthzOfs XrdOfsFS;
00016
00017 extern XrdSysError OfsEroute;
00018 extern XrdOssSys XrdOssSS;
00019 extern XrdOucTrace OfsTrace;
00020 extern void *XrdOfsIdleScan(void *);
00021
00022 extern "C"
00023 {
00024 XrdSfsFileSystem *XrdSfsGetFileSystem(XrdSfsFileSystem *native_fs,
00025 XrdSysLogger *lp,
00026 const char *configfn)
00027 {
00028 pthread_t tid;
00029 int retc;
00030
00031
00032 OfsEroute.SetPrefix("XrdTokenAuthzOfs_");
00033 OfsEroute.logger(lp);
00034 OfsEroute.Emsg("Init", "(c) 2005 CERN/Alice, XrdTokenAuthzOfs Version "
00035 XrdVSTRING);
00036
00037
00038
00039 XrdOfsFS.ConfigFN = (configfn && *configfn ? strdup(configfn) : 0);
00040 if ( XrdOfsFS.Configure(OfsEroute) ) return 0;
00041 XrdOfsFS.Config_Display(OfsEroute);
00042
00043 OfsEroute.Emsg("XrdOfsinit","initializing the XrdTokenAuthzOfs object");
00044
00045
00046
00047 if (XrdOssSS.Init(lp, configfn)) return 0;
00048
00049
00050
00051 if ((retc = XrdSysThread::Run(&tid, XrdOfsIdleScan, (void *)0)))
00052 OfsEroute.Emsg("XrdOfsinit", retc, "create idle scan thread");
00053
00054
00055
00056
00057 return (XrdSfsFileSystem*) &XrdOfsFS;
00058 }
00059 }
00060
00061
00062
00063 int
00064 XrdTokenAuthzOfsFile::open(const char *fileName,
00065 XrdSfsFileOpenMode openMode,
00066 mode_t createMode,
00067 const XrdSecClientName *client,
00068 const char *opaque)
00069 {
00070 static const char *epname = "open";
00071 TAuthzXMLreader* authz=0;
00072 bool write_once = false;
00073
00074
00075 ZTRACE(open,"lfn = " << fileName);
00076
00077 std::map<std::string,std::string> env;
00078 TTokenAuthz::Tokenize(opaque,env,"&");
00079
00080
00081 std::string vo="*";
00082 if ( (env["vo"].length()) > 0) {
00083 vo = env["vo"];
00084 }
00085
00086
00087 if (client) {
00088 if ((client->vorg) && (strlen(client->vorg)))
00089 vo = client->vorg;
00090 }
00091
00092
00093 const char* certsubject=0;
00094 if (client) {
00095 if ((client->name) && (strlen(client->name))) {
00096 certsubject = client->name;
00097 }
00098 }
00099
00100 TTokenAuthz* tkauthz = 0;
00101 if (GTRACE(ALL)) {
00102 tkauthz = TTokenAuthz::GetTokenAuthz("xrootd",true);
00103 } else {
00104 tkauthz = TTokenAuthz::GetTokenAuthz("xrootd",true);
00105 }
00106
00107
00108 std::string authzopenmode;
00109 if (!(openMode & (SFS_O_WRONLY + SFS_O_RDWR + SFS_O_CREAT + SFS_O_TRUNC))) {
00110 authzopenmode="read";
00111 } else {
00112 if (openMode & SFS_O_CREAT) {
00113 authzopenmode="write-once";
00114 } else {
00115 if (openMode & SFS_O_RDWR) {
00116 authzopenmode="read-write";
00117 }
00118 }
00119 }
00120
00121
00122
00123 #ifdef ALIEN_BACKDOOR
00124 if ( ((env["authz"].length()) == 0 ) || (env["authz"] == "alien") ) {
00125 #else
00126 if ( ((env["authz"].length()) == 0 ) ) {
00127 #endif
00128
00129 if (tkauthz->PathIsExported(fileName,vo.c_str(),certsubject)) {
00130 if (!tkauthz->PathHasAuthz(fileName,authzopenmode.c_str(),vo.c_str(),certsubject)) {
00131
00132 return XrdOfsFile::open(fileName,openMode,createMode,client,opaque);
00133 } else {
00134
00135 XrdOfsFS.Emsg(epname, error, EACCES, "give access for lfn - path has to be authorized", fileName);
00136 return XrdTokenAuthzOfs::Emsg(epname, error, EACCES, "open", fileName);
00137 }
00138 } else {
00139
00140 XrdOfsFS.Emsg(epname, error, EACCES, "give access for lfn - path not exported", fileName);
00141 return XrdTokenAuthzOfs::Emsg(epname, error, EACCES, "open", fileName);
00142 }
00143 }
00144
00145 int garesult=0;
00146 float t1,t2;
00147 garesult = tkauthz->GetAuthz(fileName,opaque,&authz,GTRACE(ALL),&t1,&t2);
00148
00149 ZTRACE(ALL,"Time for Authz decoding: " << t1 << " ms" << " / " << t2 << "ms");
00150
00151 if (garesult != TTokenAuthz::kAuthzOK) {
00152
00153 XrdOfsFS.Emsg(epname, error, tkauthz->PosixError(garesult), tkauthz->ErrorMsg(garesult) , fileName);
00154 if (authz) delete authz;
00155 return XrdTokenAuthzOfs::Emsg(epname, error, tkauthz->PosixError(garesult), "open", fileName);
00156 }
00157
00158
00159 if (!(openMode & (SFS_O_WRONLY + SFS_O_RDWR + SFS_O_CREAT + SFS_O_TRUNC))) {
00160
00161 if (strcmp(authz->GetKey((char*)fileName,"access"), "read")) {
00162
00163 XrdOfsFS.Emsg(epname, error, EACCES, "have read access for lfn", fileName);
00164 if (authz) delete authz;
00165 return XrdTokenAuthzOfs::Emsg(epname, error, EACCES, "open", fileName);
00166 }
00167 } else {
00168 if (openMode & SFS_O_CREAT) {
00169
00170 if (strcmp(authz->GetKey((char*)fileName,"access"), "write-once")) {
00171
00172 XrdOfsFS.Emsg(epname, error, EACCES, "have write access for lfn", fileName);
00173 if (authz) delete authz;
00174 return XrdTokenAuthzOfs::Emsg(epname, error, EACCES, "open", fileName);
00175 }
00176
00177 createMode |= SFS_O_MKPTH;
00178
00179 write_once = true;
00180
00181 } else {
00182 if (openMode & SFS_O_RDWR) {
00183
00184 if (strcmp(authz->GetKey((char*)fileName,"access"), "read-write")) {
00185
00186 XrdOfsFS.Emsg(epname, error, EACCES, "have read-write access for lfn", fileName);
00187 if (authz) delete authz;
00188 return XrdTokenAuthzOfs::Emsg(epname, error, EACCES, "open", fileName);
00189 } else {
00190 XrdOfsFS.Emsg(epname, error, EACCES, "have access for lfn", fileName);
00191 if (authz) delete authz;
00192 return XrdTokenAuthzOfs::Emsg(epname, error, EACCES, "open", fileName);
00193 }
00194 }
00195 }
00196 }
00197
00198
00199
00200 const char* newfilename = TTokenAuthz::GetPath(authz->GetKey((char*)fileName,"turl"));
00201 std::string copyfilename = newfilename;
00202
00203
00204
00205 if (!tkauthz->PathIsExported(newfilename,vo.c_str())) {
00206
00207 XrdOfsFS.Emsg(epname, error, EACCES, "give access for turl - path not exported", newfilename);
00208 if (authz) delete authz;
00209 return XrdTokenAuthzOfs::Emsg(epname, error, EACCES, "open", fileName);
00210 }
00211
00212
00213 if (tkauthz->CertNeedsMatch(newfilename,vo.c_str())) {
00214 if (certsubject != authz->GetKey((char*)fileName,"certsubject")) {
00215 XrdOfsFS.Emsg(epname, error, EACCES, "give access for turl - certificate subject does not match", newfilename);
00216 return XrdTokenAuthzOfs::Emsg(epname, error, EACCES, "open", fileName);
00217 }
00218 }
00219
00220
00221
00222 if ((openMode & (SFS_O_CREAT)) && (write_once)) {
00223 XrdSfsFileExistence exists_flag = (XrdSfsFileExistence) 0 ;
00224 XrdOfsFS.exists(copyfilename.c_str(),exists_flag, error, client);
00225 if (exists_flag != XrdSfsFileExistNo) {
00226 XrdOfsFS.Emsg(epname, error, EEXIST, "to open file for write - file exists for lfn", fileName);
00227 if (authz) delete authz;
00228 return XrdTokenAuthzOfs::Emsg(epname, error, EEXIST, "open", fileName);
00229 }
00230 }
00231
00232
00233 if (authz) delete authz;
00234 std::string newopaque="";
00235 return XrdOfsFile::open(copyfilename.c_str(),openMode,createMode,client,newopaque.c_str());
00236 }
00237
00238
00239
00240
00241 int
00242 XrdTokenAuthzOfs::stat(const char *Name,
00243 struct stat *buf,
00244 XrdOucErrInfo &out_error,
00245 const XrdSecEntity *client,
00246 const char *opaque) {
00247 static const char *epname = "stat";
00248 TAuthzXMLreader* authz=0;
00249 const char *tident = out_error.getErrUser();
00250
00251 ZTRACE(stat,"lfn = " << Name);
00252
00253 std::map<std::string,std::string> env;
00254 TTokenAuthz::Tokenize(opaque,env,"&");
00255
00256 std::string vo="*";
00257 if ( (env["vo"].length()) > 0) {
00258 vo = env["vo"];
00259 }
00260 TTokenAuthz* tkauthz = 0;
00261 if (GTRACE(ALL)) {
00262 tkauthz = TTokenAuthz::GetTokenAuthz("xrootd",true);
00263 } else {
00264 tkauthz = TTokenAuthz::GetTokenAuthz("xrootd",false);
00265 }
00266
00267 #ifdef ALIEN_BACKDOOR
00268 if ( ((env["authz"].length()) == 0 ) || (env["authz"] == "alien") ) {
00269 #else
00270 if ( ((env["authz"].length()) == 0 ) ) {
00271 #endif
00272
00273 if (tkauthz->PathIsExported(Name,vo.c_str())) {
00274 if (!tkauthz->PathHasAuthz(Name,"read",vo.c_str())) {
00275
00276 return XrdOfs::stat(Name,buf,out_error,client);
00277 } else {
00278
00279 XrdOfsFS.Emsg(epname, out_error, EACCES, "give access for lfn - path has to be authorized", Name);
00280 return XrdTokenAuthzOfs::Emsg(epname, out_error, EACCES, "stat", Name);
00281 }
00282 } else {
00283
00284 XrdOfsFS.Emsg(epname, out_error, EACCES, "give access for lfn - path not exported", Name);
00285 return XrdTokenAuthzOfs::Emsg(epname, out_error, EACCES, "stat", Name);
00286 }
00287 }
00288
00289
00290 int garesult=0;
00291 float t1,t2;
00292 garesult = tkauthz->GetAuthz(Name,opaque,&authz,GTRACE(ALL),&t1,&t2);
00293 ZTRACE(ALL,"Time for Authz decoding: " << t1 << " ms" << " / " << t2 << "ms");
00294
00295 if (garesult != TTokenAuthz::kAuthzOK) {
00296
00297 XrdOfsFS.Emsg(epname, out_error, tkauthz->PosixError(garesult), tkauthz->ErrorMsg(garesult) , Name);
00298 if (authz) delete authz;
00299 return XrdTokenAuthzOfs::Emsg(epname, out_error, tkauthz->PosixError(garesult), "stat", Name);
00300 }
00301
00302
00303 const char* newfilename = TTokenAuthz::GetPath(authz->GetKey(Name,"turl"));
00304 std::string copyfilename = newfilename;
00305
00306
00307 if (!tkauthz->PathIsExported(newfilename,vo.c_str())) {
00308
00309 XrdOfsFS.Emsg(epname, out_error, EACCES, "give access for turl - path not exported", newfilename);
00310 if (authz) delete authz;
00311 return XrdTokenAuthzOfs::Emsg(epname, out_error, EACCES, "open", Name);
00312 }
00313
00314 if (authz) delete authz;
00315 return XrdOfs::stat(copyfilename.c_str(),buf,out_error,client);
00316 }
00317
00318
00319
00320
00321 int
00322 XrdTokenAuthzOfs::stat(const char *Name,
00323 mode_t &mode,
00324 XrdOucErrInfo &out_error,
00325 const XrdSecEntity *client,
00326 const char *opaque) {
00327 static const char *epname = "stat";
00328
00329 TAuthzXMLreader* authz=0;
00330 const char *tident = out_error.getErrUser();
00331
00332 ZTRACE(stat,"lfn = " << Name);
00333 std::map<std::string,std::string> env;
00334 TTokenAuthz::Tokenize(opaque,env,"&");
00335
00336 std::string vo="*";
00337 if ( (env["vo"].length()) > 0) {
00338 vo = env["vo"];
00339 }
00340 TTokenAuthz* tkauthz = 0;
00341 if (GTRACE(ALL)) {
00342 tkauthz = TTokenAuthz::GetTokenAuthz("xrootd",true);
00343 } else {
00344 tkauthz = TTokenAuthz::GetTokenAuthz("xrootd",false);
00345 }
00346
00347 #ifdef ALIEN_BACKDOOR
00348 if ( ((env["authz"].length()) == 0 ) || (env["authz"] == "alien") ) {
00349 #else
00350 if ( ((env["authz"].length()) == 0 ) ) {
00351 #endif
00352
00353 if (tkauthz->PathIsExported(Name,vo.c_str())) {
00354 if (!tkauthz->PathHasAuthz(Name,"read",vo.c_str())) {
00355
00356 return XrdOfs::stat(Name,mode,out_error,client);
00357 } else {
00358
00359 XrdOfsFS.Emsg(epname, out_error, EACCES, "give access for lfn - path has to be authorized", Name);
00360 return XrdTokenAuthzOfs::Emsg(epname, out_error, EACCES, "stat", Name);
00361 }
00362 } else {
00363
00364 XrdOfsFS.Emsg(epname, out_error, EACCES, "give access for lfn - path not exported", Name);
00365 return XrdTokenAuthzOfs::Emsg(epname, out_error, EACCES, "stat", Name);
00366 }
00367 }
00368
00369
00370 int garesult=0;
00371 float t1,t2;
00372 garesult = tkauthz->GetAuthz(Name,opaque,&authz,GTRACE(ALL),&t1,&t2);
00373
00374 ZTRACE(ALL,"Time for Authz decoding: " << t1 << " ms" << " / " << t2 << "ms");
00375
00376 if (garesult != TTokenAuthz::kAuthzOK) {
00377
00378 XrdOfsFS.Emsg(epname, out_error, tkauthz->PosixError(garesult), tkauthz->ErrorMsg(garesult) , Name);
00379 if (authz) delete authz;
00380 return XrdTokenAuthzOfs::Emsg(epname, out_error, tkauthz->PosixError(garesult), "stat", Name);
00381 }
00382
00383
00384 const char* newfilename = TTokenAuthz::GetPath(authz->GetKey(Name,"turl"));
00385 std::string copyfilename = newfilename;
00386
00387
00388 if (!tkauthz->PathIsExported(newfilename,vo.c_str())) {
00389
00390 XrdOfsFS.Emsg(epname, out_error, EACCES, "give access for turl - path not exported", newfilename);
00391 if (authz) delete authz;
00392 return XrdTokenAuthzOfs::Emsg(epname, out_error, EACCES, "open", Name);
00393 }
00394
00395 if (authz) delete authz;
00396 return XrdOfs::stat(copyfilename.c_str(),mode,out_error,client);
00397 }
00398
00399
00400
00401
00402 int
00403 XrdTokenAuthzOfs::rem(const char *path,
00404 XrdOucErrInfo &out_error,
00405 const XrdSecEntity *client,
00406 const char *opaque) {
00407
00408 static const char *epname = "rem";
00409 std::string url(path);
00410 std::string filename("");
00411 const char *tident = out_error.getErrUser();
00412 TAuthzXMLreader* authz=0;
00413
00414 filename = path;
00415
00416 ZTRACE(remove,"lfn = " << filename);
00417
00418 std::map<std::string,std::string> env;
00419 TTokenAuthz::Tokenize(opaque,env,"&");
00420
00421
00422 std::string vo="*";
00423 if ( (env["vo"].length()) > 0) {
00424 vo = env["vo"];
00425 }
00426
00427 TTokenAuthz* tkauthz = 0;
00428 if (GTRACE(ALL)) {
00429 tkauthz = TTokenAuthz::GetTokenAuthz("xrootd",true);
00430 } else {
00431 tkauthz = TTokenAuthz::GetTokenAuthz("xrootd",false);
00432 }
00433
00434
00435 #ifdef ALIEN_BACKDOOR
00436 if ( ((env["authz"].length()) == 0 ) || (env["authz"] == "alien") ) {
00437 #else
00438 if ( ((env["authz"].length()) == 0 ) ) {
00439 #endif
00440
00441 if (tkauthz->PathIsExported(filename.c_str(),vo.c_str())) {
00442 if (!tkauthz->PathHasAuthz(filename.c_str(),"delete",vo.c_str())) {
00443
00444 return XrdOfs::rem(filename.c_str(),out_error,client);
00445 } else {
00446
00447 XrdOfsFS.Emsg(epname, out_error, EACCES, "give access for lfn - path has to be authorized", filename.c_str());
00448 return XrdTokenAuthzOfs::Emsg(epname, out_error, EACCES, "rem", filename.c_str());
00449 }
00450 } else {
00451
00452 XrdOfsFS.Emsg(epname, out_error, EACCES, "give access for lfn - path not exported", filename.c_str());
00453 return XrdTokenAuthzOfs::Emsg(epname, out_error, EACCES, "rem", filename.c_str());
00454 }
00455 }
00456
00457
00458 int garesult=0;
00459 float t1,t2;
00460 garesult = tkauthz->GetAuthz(filename.c_str(),opaque,&authz,GTRACE(ALL),&t1,&t2);
00461
00462 ZTRACE(ALL,"Time for Authz decoding: " << t1 << " ms" << " / " << t2 << "ms");
00463
00464 if (garesult != TTokenAuthz::kAuthzOK) {
00465
00466 XrdOfsFS.Emsg(epname, out_error, tkauthz->PosixError(garesult), tkauthz->ErrorMsg(garesult) , filename.c_str());
00467 if (authz) delete authz;
00468 return XrdTokenAuthzOfs::Emsg(epname, out_error, tkauthz->PosixError(garesult), "stat", filename.c_str());
00469 }
00470
00471
00472 const char* newfilename = TTokenAuthz::GetPath(authz->GetKey(filename.c_str(),"turl"));
00473 std::string deletefilename = newfilename;
00474
00475 if (strcmp(authz->GetKey(filename.c_str(),"access"), "delete")) {
00476 if (authz) delete authz;
00477 return -1;
00478 }
00479 if (authz) delete authz;
00480
00481
00482 if (!tkauthz->PathIsExported(newfilename,vo.c_str())) {
00483
00484 XrdOfsFS.Emsg(epname, out_error, EACCES, "give access for turl - path not exported", newfilename);
00485 if (authz) delete authz;
00486 return XrdTokenAuthzOfs::Emsg(epname, out_error, EACCES, "open", filename.c_str());
00487 }
00488
00489 return XrdOfs::rem(deletefilename.c_str(),out_error,client);
00490 }
00491