XrdAccAccess.cc

Go to the documentation of this file.
00001 /******************************************************************************/
00002 /*                                                                            */
00003 /*                       X r d A c c A c c e s s . c c                        */
00004 /*                                                                            */
00005 /* (c) 2003 by the Board of Trustees of the Leland Stanford, Jr., University  */
00006 /*                            All Rights Reserved                             */
00007 /*   Produced by Andrew Hanushevsky for Stanford University under contract    */
00008 /*              DE-AC03-76-SFO0515 with the Department of Energy              */
00009 /******************************************************************************/
00010 
00011 //         $Id: XrdAccAccess.cc 38011 2011-02-08 18:35:57Z ganis $
00012 
00013 const char *XrdAccAccessCVSID = "$Id: XrdAccAccess.cc 38011 2011-02-08 18:35:57Z ganis $";
00014 
00015 #include <stdio.h>
00016 #include <time.h>
00017 #include <sys/param.h>
00018 
00019 #include "XrdAcc/XrdAccAccess.hh"
00020 #include "XrdAcc/XrdAccCapability.hh"
00021 #include "XrdAcc/XrdAccConfig.hh"
00022 #include "XrdAcc/XrdAccGroups.hh"
00023 #include "XrdOuc/XrdOucTokenizer.hh"
00024   
00025 /******************************************************************************/
00026 /*                   E x t e r n a l   R e f e r e n c e s                    */
00027 /******************************************************************************/
00028   
00029 extern unsigned long XrdOucHashVal2(const char *KeyVal, int KeyLen);
00030 
00031 /******************************************************************************/
00032 /*           G l o b a l   C o n f i g u r a t i o n   O b j e c t            */
00033 /******************************************************************************/
00034   
00035 extern XrdAccConfig XrdAccConfiguration;
00036 
00037 /******************************************************************************/
00038 /*       Autorization Object Creation via XrdAccDefaultAuthorizeObject        */
00039 /******************************************************************************/
00040   
00041 XrdAccAuthorize *XrdAccDefaultAuthorizeObject(XrdSysLogger *lp, const char *cfn,
00042                                               const char *parm)
00043 {
00044    static XrdSysError Eroute(lp, "acc_");
00045 
00046 // Configure the authorization system
00047 //
00048    if (XrdAccConfiguration.Configure(Eroute, cfn)) return (XrdAccAuthorize *)0;
00049 
00050 // All is well, return the actual pointer to the object
00051 //
00052    return (XrdAccAuthorize *)XrdAccConfiguration.Authorization;
00053 }
00054   
00055 /******************************************************************************/
00056 /*                           C o n s t r u c t o r                            */
00057 /******************************************************************************/
00058   
00059 XrdAccAccess::XrdAccAccess(XrdSysError *erp)
00060 {
00061 // Get the audit option that we should use
00062 //
00063    Auditor = XrdAccAuditObject(erp);
00064 }
00065 
00066 /******************************************************************************/
00067 /*                                A c c e s s                                 */
00068 /******************************************************************************/
00069   
00070 XrdAccPrivs XrdAccAccess::Access(const XrdSecEntity    *Entity,
00071                                  const char            *path,
00072                                  const Access_Operation oper,
00073                                        XrdOucEnv       *Env)
00074 {
00075    XrdAccPrivs myprivs;
00076    char *gname;
00077    int accok;
00078    XrdAccGroupList *glp;
00079    XrdAccPrivCaps caps;
00080    XrdAccCapability *cp;
00081    const int plen  = strlen(path);
00082    const long phash = XrdOucHashVal2(path, plen);
00083    XrdAccAudit_Options audits = (XrdAccAudit_Options)Auditor->Auditing();
00084    const char *id   = (Entity->name ? (const char *)Entity->name : "*");
00085    const char *host = (Entity->host ? (const char *)Entity->host : "?");
00086    int isuser = (*id && (*id != '*' || id[1]));
00087 
00088 // Get a shared context for these potentially long running routines
00089 //
00090    Access_Context.Lock(xs_Shared);
00091 
00092 // Establish default privileges
00093 //
00094    if (Atab.Z_List) Atab.Z_List->Privs(caps, path, plen, phash);
00095 
00096 // Next add in the host domain privileges
00097 //
00098    if (Atab.D_List && host && (cp = Atab.D_List->Find(host)))
00099       cp->Privs(caps, path, plen, phash);
00100 
00101 // Next add in the host-specific privileges
00102 //
00103    if (Atab.H_Hash && host && (cp = Atab.H_Hash->Find(host)))
00104       cp->Privs(caps, path, plen, phash);
00105 
00106 // Check for user fungible privileges
00107 //
00108    if (isuser && Atab.X_List) Atab.X_List->Privs(caps, path, plen, phash, id);
00109 
00110 // Add in specific user privileges
00111 //
00112    if (isuser && Atab.U_Hash && (cp = Atab.U_Hash->Find(id)))
00113       cp->Privs(caps, path, plen, phash);
00114 
00115 // Next add in the group privileges. The group list either comes from the
00116 // credentials, in which case we need not have a username, or from the
00117 // standard unix-username group mapping.
00118 //
00119    if (Atab.G_Hash)
00120       {if (Entity->grps)
00121           {char gBuff[1024];
00122            XrdOucTokenizer gList(gBuff);
00123            strlcpy(gBuff, Entity->grps, sizeof(gBuff));
00124            gList.GetLine();
00125            while((gname = gList.GetToken()))
00126                 if ((cp = Atab.G_Hash->Find((const char *)gname)))
00127                    cp->Privs(caps, path, plen, phash);
00128           } else if (isuser && (glp=XrdAccConfiguration.GroupMaster.Groups(id)))
00129                     {while((gname = (char *)glp->Next()))
00130                           if ((cp = Atab.G_Hash->Find((const char *)gname)))
00131                              cp->Privs(caps, path, plen, phash);
00132                      delete glp;
00133                     }
00134       }
00135 
00136 // Now add in the netgroup privileges
00137 //
00138    if (Atab.N_Hash && id && host && 
00139        (glp = XrdAccConfiguration.GroupMaster.NetGroups(id, host)))
00140       {while((gname = (char *)glp->Next()))
00141             if ((cp = Atab.N_Hash->Find((const char *)gname)))
00142                cp->Privs(caps, path, plen, phash);
00143        delete glp;
00144       }
00145 
00146 // We are now done with looking at changeable data
00147 //
00148    Access_Context.UnLock(xs_Shared);
00149 
00150 
00151 // Compute composite privileges and see if privs need to be returned
00152 //
00153    myprivs = (XrdAccPrivs)(caps.pprivs & ~caps.nprivs);
00154    if (!oper) return (XrdAccPrivs)myprivs;
00155 
00156 // Check if auditing is enabled or whether we can do a fastaroo test
00157 //
00158    if (!audits) return (XrdAccPrivs)Test(myprivs, oper);
00159    if ((accok = Test(myprivs, oper)) && !(audits & audit_grant))
00160       return (XrdAccPrivs)accok;
00161 
00162 // Call the auditing routine and exit
00163 //
00164    return (XrdAccPrivs)Audit(accok, Entity, path, oper);
00165 }
00166   
00167 /******************************************************************************/
00168 /*                                A c c e s s                                 */
00169 /******************************************************************************/
00170   
00171 XrdAccPrivs XrdAccAccess::Access(const char *id,
00172                                  const Access_ID_Type idtype,
00173                                  const char *path,
00174                                  const Access_Operation oper)
00175 {
00176    XrdAccPrivCaps caps;
00177    XrdAccCapability *cp;
00178    XrdOucHash<XrdAccCapability> *hp;
00179    const int plen  = strlen(path);
00180    const long phash = XrdOucHashVal2(path, plen);
00181 
00182 // Select appropriate hash table for the id type
00183 //
00184    switch(idtype)
00185         {case AID_Group:      hp = Atab.G_Hash; break;
00186          case AID_Host:       hp = Atab.H_Hash; break;
00187          case AID_Netgroup:   hp = Atab.N_Hash; break;
00188          case AID_Set:        hp = Atab.S_Hash; break;
00189          case AID_Template:   hp = Atab.T_Hash; break;
00190          case AID_User:       hp = Atab.U_Hash; break;
00191          default:             hp = 0;           break;
00192         }
00193 
00194 // Get a shared context while we look up the privileges
00195 //
00196    Access_Context.Lock(xs_Shared);
00197 
00198 // Establish default privileges
00199 //
00200    if (Atab.Z_List) Atab.Z_List->Privs(caps, path, plen, phash);
00201 
00202 // Check for self-describing user template privileges if this is a user
00203 //
00204    if (idtype == AID_User && Atab.X_List)
00205       Atab.X_List->Privs(caps, path, plen, phash, id);
00206 
00207 // Check for domain privileges if this is a host
00208 //
00209    if (idtype == AID_Host && Atab.D_List && (cp = Atab.D_List->Find(id)))
00210       cp->Privs(caps, path, plen, phash, id);
00211 
00212 // Look up the specific privileges
00213 //
00214    if (hp && (cp = hp->Find(id))) cp->Privs(caps, path, plen, phash);
00215 
00216 // We are now done with looking at changeable data
00217 //
00218    Access_Context.UnLock(xs_Shared);
00219 
00220 // Perform required access check
00221 //
00222    if (oper) return (XrdAccPrivs)Test(
00223                     (XrdAccPrivs)(caps.pprivs & ~caps.nprivs), oper);
00224              return (XrdAccPrivs)(caps.pprivs & ~caps.nprivs);
00225 }
00226 
00227 /******************************************************************************/
00228 /*                                 A u d i t                                  */
00229 /******************************************************************************/
00230   
00231 int XrdAccAccess::Audit(const int              accok,
00232                         const XrdSecEntity    *Entity,
00233                         const char            *path,
00234                         const Access_Operation oper,
00235                               XrdOucEnv       *Env)
00236 {
00237 // Warning! This table must be in 1-to-1 correspondence with Access_Operation
00238 //
00239    static const char *Opername[] = {"any",             // 0
00240                                     "chmod",           // 1
00241                                     "chown",           // 2
00242                                     "create",          // 3
00243                                     "delete",          // 4
00244                                     "insert",          // 5
00245                                     "lock",            // 6
00246                                     "mkdir",           // 7
00247                                     "read",            // 8
00248                                     "readdir",         // 9
00249                                     "rename",          // 10
00250                                     "stat",            // 10
00251                                     "update"           // 12
00252                              };
00253    const char *opname = (oper > AOP_LastOp ? "???" : Opername[oper]);
00254    const char *id   = (Entity->name ? (const char *)Entity->name : "*");
00255    const char *host = (Entity->host ? (const char *)Entity->host : "?");
00256    char atype[XrdSecPROTOIDSIZE+1];
00257 
00258 // Get the protocol type in a printable format
00259 //
00260    strncpy(atype, Entity->prot, XrdSecPROTOIDSIZE);
00261    atype[XrdSecPROTOIDSIZE] = '\0';
00262 
00263 // Route the message appropriately
00264 //
00265     if (accok) Auditor->Grant(opname, Entity->tident, atype, id, host, path);
00266        else    Auditor->Deny( opname, Entity->tident, atype, id, host, path);
00267 
00268 // All done, finally
00269 //
00270    return accok;
00271 }
00272 
00273 /******************************************************************************/
00274 /*                              S w a p T a b s                               */
00275 /******************************************************************************/
00276 
00277 #define XrdAccSWAP(x) oldtab.x = Atab.x;   Atab.x  =  newtab.x; \
00278                       newtab.x = oldtab.x; oldtab.x = 0;
00279 
00280 void XrdAccAccess::SwapTabs(struct XrdAccAccess_Tables &newtab)
00281 {
00282      struct XrdAccAccess_Tables oldtab;
00283 
00284 // Get an exclusive context to change the table pointers
00285 //
00286    Access_Context.Lock(xs_Exclusive);
00287 
00288 // Save the old pointer while replacing it with the new pointer
00289 //
00290    XrdAccSWAP(D_List);
00291    XrdAccSWAP(E_List);
00292    XrdAccSWAP(G_Hash);
00293    XrdAccSWAP(H_Hash);
00294    XrdAccSWAP(N_Hash);
00295    XrdAccSWAP(S_Hash);
00296    XrdAccSWAP(T_Hash);
00297    XrdAccSWAP(U_Hash);
00298    XrdAccSWAP(X_List);
00299    XrdAccSWAP(Z_List);
00300 
00301 // When we set new access tables, we should purge the group cache
00302 //
00303    XrdAccConfiguration.GroupMaster.PurgeCache();
00304 
00305 // We can now let loose new table searchers
00306 //
00307    Access_Context.UnLock(xs_Exclusive);
00308 }
00309 
00310 /******************************************************************************/
00311 /*                                  T e s t                                   */
00312 /******************************************************************************/
00313 
00314 int XrdAccAccess::Test(const XrdAccPrivs priv,const Access_Operation oper)
00315 {
00316 
00317 // Warning! This table must be in 1-to-1 correspondence with Access_Operation
00318 //
00319    static XrdAccPrivs need[] = {XrdAccPriv_None,                 // 0
00320                                 XrdAccPriv_Chmod,                // 1
00321                                 XrdAccPriv_Chown,                // 2
00322                                 XrdAccPriv_Create,               // 3
00323                                 XrdAccPriv_Delete,               // 4
00324                                 XrdAccPriv_Insert,               // 5
00325                                 XrdAccPriv_Lock,                 // 6
00326                                 XrdAccPriv_Mkdir,                // 7
00327                                 XrdAccPriv_Read,                 // 8
00328                                 XrdAccPriv_Readdir,              // 9
00329                                 XrdAccPriv_Rename,               // 10
00330                                 XrdAccPriv_Lookup,               // 11
00331                                 XrdAccPriv_Update                // 12
00332                                };
00333    if (oper < 0 || oper > AOP_LastOp) return 0;
00334    return (int)(need[oper] & priv) == need[oper];
00335 }

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