00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
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
00027
00028
00029 extern unsigned long XrdOucHashVal2(const char *KeyVal, int KeyLen);
00030
00031
00032
00033
00034
00035 extern XrdAccConfig XrdAccConfiguration;
00036
00037
00038
00039
00040
00041 XrdAccAuthorize *XrdAccDefaultAuthorizeObject(XrdSysLogger *lp, const char *cfn,
00042 const char *parm)
00043 {
00044 static XrdSysError Eroute(lp, "acc_");
00045
00046
00047
00048 if (XrdAccConfiguration.Configure(Eroute, cfn)) return (XrdAccAuthorize *)0;
00049
00050
00051
00052 return (XrdAccAuthorize *)XrdAccConfiguration.Authorization;
00053 }
00054
00055
00056
00057
00058
00059 XrdAccAccess::XrdAccAccess(XrdSysError *erp)
00060 {
00061
00062
00063 Auditor = XrdAccAuditObject(erp);
00064 }
00065
00066
00067
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
00089
00090 Access_Context.Lock(xs_Shared);
00091
00092
00093
00094 if (Atab.Z_List) Atab.Z_List->Privs(caps, path, plen, phash);
00095
00096
00097
00098 if (Atab.D_List && host && (cp = Atab.D_List->Find(host)))
00099 cp->Privs(caps, path, plen, phash);
00100
00101
00102
00103 if (Atab.H_Hash && host && (cp = Atab.H_Hash->Find(host)))
00104 cp->Privs(caps, path, plen, phash);
00105
00106
00107
00108 if (isuser && Atab.X_List) Atab.X_List->Privs(caps, path, plen, phash, id);
00109
00110
00111
00112 if (isuser && Atab.U_Hash && (cp = Atab.U_Hash->Find(id)))
00113 cp->Privs(caps, path, plen, phash);
00114
00115
00116
00117
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
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
00147
00148 Access_Context.UnLock(xs_Shared);
00149
00150
00151
00152
00153 myprivs = (XrdAccPrivs)(caps.pprivs & ~caps.nprivs);
00154 if (!oper) return (XrdAccPrivs)myprivs;
00155
00156
00157
00158 if (!audits) return (XrdAccPrivs)Test(myprivs, oper);
00159 if ((accok = Test(myprivs, oper)) && !(audits & audit_grant))
00160 return (XrdAccPrivs)accok;
00161
00162
00163
00164 return (XrdAccPrivs)Audit(accok, Entity, path, oper);
00165 }
00166
00167
00168
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
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
00195
00196 Access_Context.Lock(xs_Shared);
00197
00198
00199
00200 if (Atab.Z_List) Atab.Z_List->Privs(caps, path, plen, phash);
00201
00202
00203
00204 if (idtype == AID_User && Atab.X_List)
00205 Atab.X_List->Privs(caps, path, plen, phash, id);
00206
00207
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
00213
00214 if (hp && (cp = hp->Find(id))) cp->Privs(caps, path, plen, phash);
00215
00216
00217
00218 Access_Context.UnLock(xs_Shared);
00219
00220
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
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
00238
00239 static const char *Opername[] = {"any",
00240 "chmod",
00241 "chown",
00242 "create",
00243 "delete",
00244 "insert",
00245 "lock",
00246 "mkdir",
00247 "read",
00248 "readdir",
00249 "rename",
00250 "stat",
00251 "update"
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
00259
00260 strncpy(atype, Entity->prot, XrdSecPROTOIDSIZE);
00261 atype[XrdSecPROTOIDSIZE] = '\0';
00262
00263
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
00269
00270 return accok;
00271 }
00272
00273
00274
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
00285
00286 Access_Context.Lock(xs_Exclusive);
00287
00288
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
00302
00303 XrdAccConfiguration.GroupMaster.PurgeCache();
00304
00305
00306
00307 Access_Context.UnLock(xs_Exclusive);
00308 }
00309
00310
00311
00312
00313
00314 int XrdAccAccess::Test(const XrdAccPrivs priv,const Access_Operation oper)
00315 {
00316
00317
00318
00319 static XrdAccPrivs need[] = {XrdAccPriv_None,
00320 XrdAccPriv_Chmod,
00321 XrdAccPriv_Chown,
00322 XrdAccPriv_Create,
00323 XrdAccPriv_Delete,
00324 XrdAccPriv_Insert,
00325 XrdAccPriv_Lock,
00326 XrdAccPriv_Mkdir,
00327 XrdAccPriv_Read,
00328 XrdAccPriv_Readdir,
00329 XrdAccPriv_Rename,
00330 XrdAccPriv_Lookup,
00331 XrdAccPriv_Update
00332 };
00333 if (oper < 0 || oper > AOP_LastOp) return 0;
00334 return (int)(need[oper] & priv) == need[oper];
00335 }