XrdTokenAuthzOfs.cc

Go to the documentation of this file.
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 // if you want to allow the alien shell to do normal work define ALIEN_BACKDOOR
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 // Do the herald thing
00031 //
00032    OfsEroute.SetPrefix("XrdTokenAuthzOfs_");
00033    OfsEroute.logger(lp);
00034    OfsEroute.Emsg("Init", "(c) 2005 CERN/Alice, XrdTokenAuthzOfs Version "
00035                           XrdVSTRING);
00036 
00037 // Initialize the subsystems
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 // Initialize the target storage system
00046 //
00047    if (XrdOssSS.Init(lp, configfn)) return 0;
00048 
00049 // Start a thread to periodically scan for idle file handles
00050 //
00051    if ((retc = XrdSysThread::Run(&tid, XrdOfsIdleScan, (void *)0)))
00052       OfsEroute.Emsg("XrdOfsinit", retc, "create idle scan thread");
00053 
00054 // All done, we can return the callout vector to these routines.
00055 //
00056 
00057    return (XrdSfsFileSystem*) &XrdOfsFS;
00058 }
00059 }
00060 /////////////////////////////////////////////////////////////////////////////////////////
00061 // the authz open function
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   // set the vo string from the opaque information
00081   std::string vo="*";
00082   if ( (env["vo"].length()) > 0) {
00083     vo = env["vo"];
00084   }
00085   
00086   // if we have the vo defined in the credentials, use this one
00087   if (client) {
00088     if ((client->vorg) && (strlen(client->vorg)))
00089       vo = client->vorg;
00090   }
00091 
00092   // set the certificate, if we have one
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); // with debug output
00103   } else {
00104     tkauthz = TTokenAuthz::GetTokenAuthz("xrootd",true);// no debug output
00105   }
00106 
00107   // set the opening mode
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   // if no authorization info is provided, we do the namespace export+authz checks
00123 #ifdef ALIEN_BACKDOOR
00124   if ( ((env["authz"].length()) == 0 ) || (env["authz"] == "alien") ) {
00125 #else
00126   if ( ((env["authz"].length()) == 0 ) ) {
00127 #endif
00128     // check if the directory asked is exported 
00129     if (tkauthz->PathIsExported(fileName,vo.c_str(),certsubject)) {
00130       if (!tkauthz->PathHasAuthz(fileName,authzopenmode.c_str(),vo.c_str(),certsubject)) {
00131         // the pass through 
00132         return XrdOfsFile::open(fileName,openMode,createMode,client,opaque);        
00133       } else {
00134         // path needs authorization
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       // path is not exported for this VO
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     // if the authorization decoding failed for any reason
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   // check the access permissions
00159   if (!(openMode & (SFS_O_WRONLY + SFS_O_RDWR + SFS_O_CREAT + SFS_O_TRUNC))) {
00160     // check that we have the READ access
00161     if (strcmp(authz->GetKey((char*)fileName,"access"), "read")) {
00162       // we have no read access
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       // check that we have the WRITE access
00170       if (strcmp(authz->GetKey((char*)fileName,"access"), "write-once")) {
00171         // we have no write-once access
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       // force the creation of that directory
00177       createMode |= SFS_O_MKPTH;
00178       // force the write-once check
00179       write_once = true;
00180 
00181     } else {
00182       if (openMode & SFS_O_RDWR) {
00183         // check that we have the READ-WRITE access
00184         if (strcmp(authz->GetKey((char*)fileName,"access"), "read-write")) {
00185           // we have no read-write access
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   // get the turl
00200   const char* newfilename = TTokenAuthz::GetPath(authz->GetKey((char*)fileName,"turl"));
00201   std::string copyfilename = newfilename;
00202 
00203   
00204   // check if the asked filename is exported 
00205   if (!tkauthz->PathIsExported(newfilename,vo.c_str())) {
00206     // path is not exported for this VO
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   // do certifcate check, if it is required
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   // if we are in write mode create the full directory path
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 // the authz stat function
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   // set the vo string from the opaque information
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); // with debug output
00263   } else {
00264     tkauthz = TTokenAuthz::GetTokenAuthz("xrootd",false);// no debug output
00265   }
00266   // if no authorization info is provided, we do the namespace export+authz checks
00267 #ifdef ALIEN_BACKDOOR
00268   if ( ((env["authz"].length()) == 0 ) || (env["authz"] == "alien") ) {
00269 #else
00270   if ( ((env["authz"].length()) == 0 ) ) {
00271 #endif
00272     // check if the directory asked is exported 
00273     if (tkauthz->PathIsExported(Name,vo.c_str())) {
00274       if (!tkauthz->PathHasAuthz(Name,"read",vo.c_str())) {
00275         // the pass through 
00276         return XrdOfs::stat(Name,buf,out_error,client);
00277       } else {
00278         // path needs authorization
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       // path is not exported for this VO
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   // get the authorization data
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     // if the authorization decoding failed for any reason
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   // get the turl
00303   const char* newfilename = TTokenAuthz::GetPath(authz->GetKey(Name,"turl"));
00304   std::string copyfilename = newfilename;
00305 
00306   // check if the asked filename is exported 
00307   if (!tkauthz->PathIsExported(newfilename,vo.c_str())) {
00308     // path is not exported for this VO
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 // the authz stat function
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   // set the vo string from the opaque information
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); // with debug output
00343   } else {
00344     tkauthz = TTokenAuthz::GetTokenAuthz("xrootd",false);// no debug output
00345   }
00346   // if no authorization info is provided, we do the namespace export+authz checks
00347 #ifdef ALIEN_BACKDOOR
00348   if ( ((env["authz"].length()) == 0 ) || (env["authz"] == "alien") ) {
00349 #else
00350   if ( ((env["authz"].length()) == 0 ) ) {
00351 #endif
00352     // check if the directory asked is exported 
00353     if (tkauthz->PathIsExported(Name,vo.c_str())) {
00354       if (!tkauthz->PathHasAuthz(Name,"read",vo.c_str())) {
00355         // the pass through 
00356         return XrdOfs::stat(Name,mode,out_error,client);
00357       } else {
00358         // path needs authorization
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       // path is not exported for this VO
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   // get the authorization data
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     // if the authorization decoding failed for any reason
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   // get the turl
00384   const char* newfilename = TTokenAuthz::GetPath(authz->GetKey(Name,"turl"));
00385   std::string copyfilename = newfilename;
00386 
00387   // check if the asked filename is exported 
00388   if (!tkauthz->PathIsExported(newfilename,vo.c_str())) {
00389     // path is not exported for this VO
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 // the authz rem function
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   // set the vo string from the opaque information
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); // with debug output
00430   } else {
00431     tkauthz = TTokenAuthz::GetTokenAuthz("xrootd",false);// no debug output
00432   }
00433 
00434   // if no authorization info is provided, we do the namespace export+authz checks
00435 #ifdef ALIEN_BACKDOOR
00436   if ( ((env["authz"].length()) == 0 ) || (env["authz"] == "alien") ) {
00437 #else
00438   if ( ((env["authz"].length()) == 0 ) ) {
00439 #endif
00440     // check if the directory asked is exported 
00441     if (tkauthz->PathIsExported(filename.c_str(),vo.c_str())) {
00442       if (!tkauthz->PathHasAuthz(filename.c_str(),"delete",vo.c_str())) {
00443         // the pass through 
00444         return XrdOfs::rem(filename.c_str(),out_error,client);
00445       } else {
00446         // path needs authorization
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       // path is not exported for this VO
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   // get the authorization data
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     // if the authorization decoding failed for any reason
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   // get the turl
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   // check if the asked filename is exported 
00482   if (!tkauthz->PathIsExported(newfilename,vo.c_str())) {
00483     // path is not exported for this VO
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 

Generated on Tue Jul 5 14:47:03 2011 for ROOT_528-00b_version by  doxygen 1.5.1