XrdAccConfig.cc

Go to the documentation of this file.
00001 /******************************************************************************/
00002 /*                                                                            */
00003 /*                       X r d A c c C o n f i g . 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 Deprtment of Energy             */
00009 /******************************************************************************/
00010 
00011 //         $Id: XrdAccConfig.cc 24468 2008-06-22 16:47:03Z ganis $
00012 
00013 const char *XrdAccConfigCVSID = "$Id: XrdAccConfig.cc 24468 2008-06-22 16:47:03Z ganis $";
00014 
00015 /*
00016    The routines in this file handle authorization system initialization.
00017 
00018    These routines are thread-safe if compiled with:
00019    AIX: -D_THREAD_SAFE
00020    SUN: -D_REENTRANT
00021 */
00022   
00023 #include <unistd.h>
00024 #include <ctype.h>
00025 #include <fcntl.h>
00026 #include <strings.h>
00027 #include <stdio.h>
00028 #include <time.h>
00029 #include <sys/param.h>
00030 #include <sys/stat.h>
00031 #include <sys/types.h>
00032 
00033 #include "XrdOuc/XrdOucLock.hh"
00034 #include "XrdOuc/XrdOucEnv.hh"
00035 #include "XrdSys/XrdSysError.hh"
00036 #include "XrdSys/XrdSysHeaders.hh"
00037 #include "XrdOuc/XrdOucStream.hh"
00038 #include "XrdAcc/XrdAccAccess.hh"
00039 #include "XrdAcc/XrdAccAudit.hh"
00040 #include "XrdAcc/XrdAccConfig.hh"
00041 #include "XrdAcc/XrdAccGroups.hh"
00042 #include "XrdAcc/XrdAccCapability.hh"
00043 
00044 /******************************************************************************/
00045 /*           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            */
00046 /******************************************************************************/
00047   
00048 // The following is the single configuration object. Other objects needing
00049 // access to this object should simply declare an extern to it.
00050 //
00051 XrdAccConfig XrdAccConfiguration;
00052 
00053 /******************************************************************************/
00054 /*                               d e f i n e s                                */
00055 /******************************************************************************/
00056 
00057 #define TS_Xeq(x,m)   if (!strcmp(x,var)) return m(Config,Eroute);
00058 
00059 #define TS_Str(x,m)   if (!strcmp(x,var)) {free(m); m = strdup(val); return 0;}
00060 
00061 #define TS_Chr(x,m)   if (!strcmp(x,var)) {m = val[0]; return 0;}
00062 
00063 #define TS_Bit(x,m,v) if (!strcmp(x,var)) {m |= v; return 0;}
00064 
00065 #define ACC_PGO 0x0001
00066 
00067 /******************************************************************************/
00068 /*                    E x t e r n a l   F u n c t i o n s                     */
00069 /******************************************************************************/
00070 /******************************************************************************/
00071 /*                  o o a c c _ C o n f i g _ R e f r e s h                   */
00072 /******************************************************************************/
00073 
00074 void *XrdAccConfig_Refresh( void *start_data )
00075 {
00076    XrdSysError *Eroute = (XrdSysError *)start_data;
00077 
00078 // Get the number of seconds between refreshes
00079 //
00080    struct timespec naptime = {(time_t)XrdAccConfiguration.AuthRT, 0};
00081 
00082 // Now loop until the bitter end
00083 //
00084    while(1)
00085         {nanosleep(&naptime, 0); XrdAccConfiguration.ConfigDB(1, *Eroute);}
00086    return (void *)0;
00087 }
00088 
00089 /******************************************************************************/
00090 /*                           C o n s t r u c t o r                            */
00091 /******************************************************************************/
00092   
00093 XrdAccConfig::XrdAccConfig()
00094 {
00095 
00096 // Initialize path value and databse pointer to nil
00097 //
00098    dbpath        = strdup("/opt/xrd/etc/Authfile");
00099    Database      = 0;
00100    Authorization = 0;
00101 
00102 // Establish other defaults
00103 //
00104    ConfigDefaults();
00105 }
00106 
00107 /******************************************************************************/
00108 /*                             C o n f i g u r e                              */
00109 /******************************************************************************/
00110   
00111 int XrdAccConfig::Configure(XrdSysError &Eroute, const char *cfn) {
00112 /*
00113   Function: Establish default values using a configuration file.
00114 
00115   Input:    None.
00116 
00117   Output:   0 upon success or !0 otherwise.
00118 */
00119    char *var;
00120    int  retc, NoGo = 0, Cold = (Database == 0);
00121    pthread_t reftid;
00122 
00123 // Print warm-up message
00124 //
00125    Eroute.Say("++++++ Authorization system initialization started.");
00126 
00127 // Process the configuration file and authorization database
00128 //
00129    if (!(Authorization = new XrdAccAccess(&Eroute))
00130    ||   (NoGo = ConfigFile(Eroute, cfn))
00131    ||   (NoGo = ConfigDB(0, Eroute)))
00132        {if (Authorization) {delete Authorization, Authorization = 0;}
00133         NoGo = 1;
00134        }
00135 
00136 // Start a refresh thread unless this was a refresh thread call
00137 //
00138    if (Cold && !NoGo)
00139       {if ((retc=XrdSysThread::Run(&reftid,XrdAccConfig_Refresh,(void *)&Eroute)))
00140           Eroute.Emsg("ConfigDB",retc,"start refresh thread.");
00141       }
00142 
00143 // All done
00144 //
00145    var = (NoGo > 0 ? (char *)"failed." : (char *)"completed.");
00146    Eroute.Say("------ Authorization system initialization ", var);
00147    return (NoGo > 0);
00148 }
00149   
00150 /******************************************************************************/
00151 /*                              C o n f i g D B                               */
00152 /******************************************************************************/
00153   
00154 int XrdAccConfig::ConfigDB(int Warm, XrdSysError &Eroute)
00155 {
00156 /*
00157   Function: Establish default values using a configuration file.
00158 
00159   Input:    None.
00160 
00161   Output:   0 upon success or !0 otherwise.
00162 */
00163    char buff[128];
00164    int  retc, anum = 0, NoGo = 0;
00165    struct XrdAccAccess_Tables tabs;
00166    XrdOucLock cdb_Lock(&Config_Context);
00167 
00168 // Indicate type of start we are doing
00169 //
00170    if (!Database) NoGo = !(Database = XrdAccAuthDBObject(&Eroute));
00171       else if (Warm && !Database->Changed(dbpath)) return 0;
00172 
00173 // Try to open the authorization database
00174 //
00175    if (!Database || !Database->Open(Eroute, dbpath)) return 1;
00176 
00177 // Allocate new hash tables
00178 //
00179    if (!(tabs.G_Hash = new XrdOucHash<XrdAccCapability>()) ||
00180        !(tabs.H_Hash = new XrdOucHash<XrdAccCapability>()) ||
00181        !(tabs.N_Hash = new XrdOucHash<XrdAccCapability>()) ||
00182        !(tabs.T_Hash = new XrdOucHash<XrdAccCapability>()) ||
00183        !(tabs.U_Hash = new XrdOucHash<XrdAccCapability>()) )
00184       {Eroute.Emsg("ConfigDB","Insufficient storage for id tables.");
00185        Database->Close(); return 1;
00186       }
00187 
00188 // Now start processing records until eof.
00189 //
00190    while((retc = ConfigDBrec(Eroute, tabs))) {NoGo |= retc < 0; anum++;}
00191    snprintf(buff, sizeof(buff), "%d auth entries processed in ", anum);
00192    Eroute.Say("Config ", buff, dbpath);
00193 
00194 // All done, close the database and return if we failed
00195 //
00196    if (!Database->Close() || NoGo) return 1;
00197 
00198 // Set the access control tables
00199 //
00200    if (!tabs.G_Hash->Num()) {delete tabs.G_Hash; tabs.G_Hash=0;}
00201    if (!tabs.H_Hash->Num()) {delete tabs.H_Hash; tabs.H_Hash=0;}
00202    if (!tabs.N_Hash->Num()) {delete tabs.N_Hash; tabs.N_Hash=0;}
00203    if (!tabs.T_Hash->Num()) {delete tabs.T_Hash; tabs.T_Hash=0;}
00204    if (!tabs.U_Hash->Num()) {delete tabs.U_Hash; tabs.U_Hash=0;}
00205    Authorization->SwapTabs(tabs);
00206 
00207 // All done
00208 //
00209    return NoGo;
00210 }
00211 
00212 /******************************************************************************/
00213 /*                     P r i v a t e   F u n c t i o n s                      */
00214 /******************************************************************************/
00215 /******************************************************************************/
00216 /*        C o n f i g   F i l e   P r o c e s s i n g   M e t h o d s         */
00217 /******************************************************************************/
00218   
00219 int XrdAccConfig::ConfigFile(XrdSysError &Eroute, const char *ConfigFN) {
00220 /*
00221   Function: Establish default values using a configuration file.
00222 
00223   Input:    None.
00224 
00225   Output:   1 - Processing failed.
00226             0 - Processing completed successfully.
00227            -1 = Security is to be disabled by request.
00228 */
00229    char *var;
00230    int  cfgFD, retc, NoGo = 0, recs = 0;
00231    XrdOucEnv myEnv;
00232    XrdOucStream Config(&Eroute, getenv("XRDINSTANCE"), &myEnv, "=====> ");
00233 
00234 // If there is no config file, complain
00235 //
00236    if( !ConfigFN || !*ConfigFN)
00237      {Eroute.Emsg("Config", "Authorization configuration file not specified.");
00238       return 1;
00239      } 
00240 
00241 // Check if security is to be disabled
00242 //
00243    if (!strcmp(ConfigFN, "none"))
00244       {Eroute.Emsg("Config", "Authorization system deactivated.");
00245        return -1;
00246       }
00247 
00248 // Try to open the configuration file.
00249 //
00250    if ( (cfgFD = open(ConfigFN, O_RDONLY, 0)) < 0)
00251       {Eroute.Emsg("Config", errno, "open config file", ConfigFN);
00252        return 1;
00253       }
00254    Eroute.Emsg("Config","Authorization system using configuration in",ConfigFN);
00255 
00256 // Now start reading records until eof.
00257 //
00258    ConfigDefaults(); Config.Attach(cfgFD); Config.Tabs(0);
00259    while((var = Config.GetMyFirstWord()))
00260         {if (!strncmp(var, "acc.", 2))
00261             {recs++;
00262              if (ConfigXeq(var+4, Config, Eroute)) {Config.Echo(); NoGo = 1;}
00263             }
00264         }
00265 
00266 // Now check if any errors occured during file i/o
00267 //
00268    if ((retc = Config.LastError()))
00269       NoGo = Eroute.Emsg("Config",-retc,"read config file",ConfigFN);
00270       else {char buff[128];
00271             snprintf(buff, sizeof(buff), 
00272                      "%d authorization directives processed in ", recs);
00273             Eroute.Say("Config ", buff, ConfigFN);
00274            }
00275    Config.Close();
00276 
00277 // Set external options, as needed
00278 //
00279    if (options & ACC_PGO) GroupMaster.SetOptions(Primary_Only);
00280 
00281 // All done
00282 //
00283    return NoGo;
00284 }
00285 
00286 /******************************************************************************/
00287 /*                        C o n f i g D e f a u l t s                         */
00288 /******************************************************************************/
00289 
00290 void XrdAccConfig::ConfigDefaults()
00291 {
00292    AuthRT   = 60*60*12;
00293    options  = 0;
00294 }
00295   
00296 /******************************************************************************/
00297 /*                             C o n f i g X e q                              */
00298 /******************************************************************************/
00299   
00300 int XrdAccConfig::ConfigXeq(char *var, XrdOucStream &Config, XrdSysError &Eroute)
00301 {
00302 
00303 // Fan out based on the variable
00304 //
00305    TS_Xeq("audit",         xaud);
00306    TS_Xeq("authdb",        xdbp);
00307    TS_Xeq("authrefresh",   xart);
00308    TS_Xeq("gidlifetime",   xglt);
00309    TS_Xeq("gidretran",     xgrt);
00310    TS_Xeq("nisdomain",     xnis);
00311    TS_Bit("pgo",           options, ACC_PGO);
00312 
00313 // No match found, complain.
00314 //
00315    Eroute.Emsg("Config", "unknown directive", var);
00316    Config.Echo();
00317    return 1;
00318 }
00319   
00320 /******************************************************************************/
00321 /*                                  x a u d                                   */
00322 /******************************************************************************/
00323 
00324 /* Function: xaud
00325 
00326    Purpose:  To parse the directive: audit <options>
00327 
00328              options:
00329 
00330              deny     audit access denials.
00331              grant    audit access grants.
00332              none     audit is disabled.
00333 
00334    Output: 0 upon success or !0 upon failure.
00335 */
00336 
00337 int XrdAccConfig::xaud(XrdOucStream &Config, XrdSysError &Eroute)
00338 {
00339     static struct auditopts {const char *opname; int opval;} audopts[] =
00340        {
00341         {"deny",     (int)audit_deny},
00342         {"grant",    (int)audit_grant}
00343        };
00344     int i, audval = 0, numopts = sizeof(audopts)/sizeof(struct auditopts);
00345     char *val;
00346 
00347     val = Config.GetWord();
00348     if (!val || !val[0])
00349        {Eroute.Emsg("Config", "audit option not specified"); return 1;}
00350     while (val && val[0])
00351           {if (!strcmp(val, "none")) audval = (int)audit_none;
00352               else for (i = 0; i < numopts; i++)
00353                        {if (!strcmp(val, audopts[i].opname))
00354                            {audval |= audopts[i].opval; break;}
00355                         if (i >= numopts)
00356                            {Eroute.Emsg("Config","invalid audit option -",val);
00357                             return 1;
00358                            }
00359                        }
00360           val = Config.GetWord();
00361          }
00362     Authorization->Auditor->setAudit((XrdAccAudit_Options)audval);
00363     return 0;
00364 }
00365 
00366 /******************************************************************************/
00367 /*                                  x a r t                                   */
00368 /******************************************************************************/
00369 
00370 /* Function: xart
00371 
00372    Purpose:  To parse the directive: authrefresh <seconds>
00373 
00374              <seconds> minimum number of seconds between aythdb refreshes.
00375 
00376    Output: 0 upon success or !0 upon failure.
00377 */
00378 
00379 int XrdAccConfig::xart(XrdOucStream &Config, XrdSysError &Eroute)
00380 {
00381     char *val;
00382     int reft;
00383 
00384       val = Config.GetWord();
00385       if (!val || !val[0])
00386          {Eroute.Emsg("Config","authrefresh value not specified");return 1;}
00387       if (XrdOuca2x::a2tm(Eroute,"authrefresh value",val,&reft,60))
00388          return 1;
00389       AuthRT = reft;
00390       return 0;
00391 }
00392 
00393 /******************************************************************************/
00394 /*                                  x d b p                                   */
00395 /******************************************************************************/
00396 
00397 /* Function: xdbp
00398 
00399    Purpose:  To parse the directive: authdb <path>
00400 
00401              <path>    is the path to the authorization database.
00402 
00403    Output: 0 upon success or !0 upon failure.
00404 */
00405 
00406 int XrdAccConfig::xdbp(XrdOucStream &Config, XrdSysError &Eroute)
00407 {
00408     char *val;
00409 
00410       val = Config.GetWord();
00411       if (!val || !val[0])
00412          {Eroute.Emsg("Config","authdb path not specified");return 1;}
00413       dbpath = strdup(val);
00414       return 0;
00415 }
00416   
00417 /******************************************************************************/
00418 /*                                  x g l t                                   */
00419 /******************************************************************************/
00420 
00421 /* Function: xglt
00422 
00423    Purpose:  To parse the directive: gidlifetime <seconds>
00424 
00425              <seconds> maximum number of seconds to cache gid information.
00426 
00427    Output: 0 upon success or !0 upon failure.
00428 */
00429 
00430 int XrdAccConfig::xglt(XrdOucStream &Config, XrdSysError &Eroute)
00431 {
00432     char *val;
00433     int reft;
00434 
00435       val = Config.GetWord();
00436       if (!val || !val[0])
00437          {Eroute.Emsg("Config","gidlifetime value not specified");return 1;}
00438       if (XrdOuca2x::a2tm(Eroute,"gidlifetime value",val,&reft,60))
00439          return 1;
00440       GroupMaster.SetLifetime(reft);
00441       return 0;
00442 }
00443 
00444 /******************************************************************************/
00445 /*                                  x g r t                                   */
00446 /******************************************************************************/
00447 
00448 /* Function: xgrt
00449 
00450    Purpose:  To parse the directive: gidretran <gidlist>
00451 
00452              <gidlist> is a list of blank separated gid's that must be
00453                        retranslated.
00454 
00455    Output: 0 upon success or !0 upon failure.
00456 */
00457 
00458 int XrdAccConfig::xgrt(XrdOucStream &Config, XrdSysError &Eroute)
00459 {
00460     char *val;
00461     int gid;
00462 
00463     val = Config.GetWord();
00464     if (!val || !val[0])
00465        {Eroute.Emsg("Config","gidretran value not specified"); return 1;}
00466 
00467     while (val && val[0])
00468       {if (XrdOuca2x::a2i(Eroute, "gid", val, &gid, 0)) return 1;
00469        if (GroupMaster.Retran((gid_t)gid) < 0)
00470           {Eroute.Emsg("Config", "to many gidretran gid's"); return 1;}
00471        val = Config.GetWord();
00472       }
00473     return 0;
00474 }
00475 
00476 /******************************************************************************/
00477 /*                                  x n i s                                   */
00478 /******************************************************************************/
00479 
00480 /* Function: xnis
00481 
00482    Purpose:  To parse the directive: nisdomain <domain>
00483 
00484              <domain>  the NIS domain to be used for nis look-ups.
00485 
00486    Output: 0 upon success or !0 upon failure.
00487 */
00488 
00489 int XrdAccConfig::xnis(XrdOucStream &Config, XrdSysError &Eroute)
00490 {
00491     char *val;
00492 
00493       val = Config.GetWord();
00494       if (!val || !val[0])
00495          {Eroute.Emsg("Config","nisdomain value not specified");return 1;}
00496       GroupMaster.SetDomain(strdup(val));
00497       return 0;
00498 }
00499   
00500 /******************************************************************************/
00501 /*                   D a t a b a s e   P r o c e s s i n g                    */
00502 /******************************************************************************/
00503 /******************************************************************************/
00504 /*                           C o n f i g D B r e c                            */
00505 /******************************************************************************/
00506 
00507 int XrdAccConfig::ConfigDBrec(XrdSysError &Eroute,
00508                             struct XrdAccAccess_Tables &tabs)
00509 {
00510 // The following enum is here for convenience
00511 //
00512     enum DB_RecType {  Group_ID = 'g',
00513                         Host_ID = 'h',
00514                       Netgrp_ID = 'n',
00515                          Set_ID = 's',
00516                     Template_ID = 't',
00517                         User_ID = 'u',
00518                           No_ID = 0
00519                     };
00520     char *authid, rtype, *atype, *path, *privs;
00521     int alluser = 0, anyuser = 0, domname = 0, NoGo = 0;
00522     DB_RecType rectype;
00523     XrdOucHash<XrdAccCapability> *hp;
00524     XrdAccGroupType gtype = XrdAccNoGroup;
00525     XrdAccPrivCaps xprivs;
00526     XrdAccCapability mycap((char *)"", xprivs), *currcap, *lastcap = &mycap;
00527     XrdAccCapName *ncp;
00528   
00529    // Prepare the next record in the database
00530    //
00531    if (!(rtype = Database->getRec(&authid))) return 0;
00532    rectype = (DB_RecType)rtype;
00533 
00534    // Set up to handle the particular record
00535    //
00536    switch(rectype)
00537          {case    Group_ID: hp = tabs.G_Hash; atype = (char *)"group";
00538                             gtype=XrdAccUnixGroup;
00539                             break;
00540           case     Host_ID: hp = tabs.H_Hash; atype = (char *)"host";
00541                             domname = (authid[0] == '.');
00542                             break;
00543           case      Set_ID: hp = 0;           atype = (char *)"set";
00544                             break;
00545           case   Netgrp_ID: hp = tabs.N_Hash; atype = (char *)"netgrp";
00546                             gtype=XrdAccNetGroup;
00547                             break;
00548           case Template_ID: hp = tabs.T_Hash; atype = (char *)"template";
00549                             break;
00550           case     User_ID: hp = tabs.U_Hash; atype = (char *)"user";
00551                             alluser = (authid[0] == '*' && !authid[1]);
00552                             anyuser = (authid[0] == '=' && !authid[1]);
00553                             break;
00554                 default:    hp = 0;
00555                             break;
00556          }
00557 
00558    // Check if we have an invalid or unsupported id-type
00559    //
00560    if (!hp) {char badtype[2] = {rtype, '\0'};
00561              Eroute.Emsg("ConfigXeq", "Invalid id type -", badtype);
00562              return -1;
00563             }
00564 
00565    // Check if this id is already defined in the table
00566    //
00567    if ((domname && tabs.D_List && tabs.D_List->Find((const char *)authid))
00568    ||  (alluser && tabs.Z_List) || (anyuser && tabs.X_List) || hp->Find(authid))
00569       {Eroute.Emsg("ConfigXeq", "duplicate id -", authid);
00570        return -1;
00571       }
00572 
00573    // Add this ID to the appropriate group object constants table
00574    //
00575    if (gtype) GroupMaster.AddName(gtype, (const char *)authid);
00576 
00577    // Now start getting <path> <priv> pairs until we hit the logical end
00578    //
00579    while(1) {NoGo = 0;
00580              if (!Database->getPP(&path, &privs)) break;
00581              if (!path) continue;      // Skip pathless entries
00582              NoGo = 1;
00583              if (*path != '/')
00584                 {if ((currcap = tabs.T_Hash->Find(path)))
00585                     currcap = new XrdAccCapability(currcap);
00586                     else {Eroute.Emsg("ConfigXeq", "Missing template -", path);
00587                           break;
00588                          }
00589                 } else {
00590                   if (!privs)
00591                      {Eroute.Emsg("ConfigXeq", "Missing privs for path", path);
00592                       break;
00593                      }
00594                   if (!PrivsConvert(privs, xprivs))
00595                      {Eroute.Emsg("ConfigXeq", "Invalid privs -", privs);
00596                       break;
00597                      }
00598                   currcap = new XrdAccCapability(path, xprivs);
00599                 }
00600              lastcap->Add(currcap);
00601              lastcap = currcap;
00602             }
00603 
00604    // Check if all went well
00605    //
00606    if (NoGo) return -1;
00607 
00608    // Check if any capabilities were specified
00609    //
00610    if (!mycap.Next())
00611       {Eroute.Emsg("ConfigXeq", "no capabilities specified for", authid);
00612        return -1;
00613       }
00614 
00615    // Insert the capability into the appropriate table/list
00616    //
00617         if (domname)
00618            {if (!(ncp = new XrdAccCapName(authid, mycap.Next())))
00619                {Eroute.Emsg("ConfigXeq","unable to add id",authid); return -1;}
00620             if (tabs.E_List) tabs.E_List->Add(ncp);
00621                else tabs.D_List = ncp;
00622             tabs.E_List = ncp;
00623            }
00624    else if (anyuser) tabs.X_List = mycap.Next();
00625    else if (alluser) tabs.Z_List = mycap.Next();
00626    else    hp->Add(authid, mycap.Next());
00627 
00628    // All done
00629    //
00630    mycap.Add((XrdAccCapability *)0);
00631    return 1;
00632 }
00633   
00634 /******************************************************************************/
00635 /*                          P r i v s C o n v e r t                           */
00636 /******************************************************************************/
00637   
00638 int XrdAccConfig::PrivsConvert(char *privs, XrdAccPrivCaps &ctab)
00639 {
00640     int i = 0;
00641     XrdAccPrivs ptab[] = {XrdAccPriv_None, XrdAccPriv_None}; // Speed conversion here
00642 
00643     // Convert the privs
00644     //
00645     while(*privs)
00646          {switch((XrdAccPrivSpec)(*privs))
00647                 {case    All_Priv:
00648                             ptab[i] = (XrdAccPrivs)(ptab[i]|XrdAccPriv_All);
00649                             break;
00650                  case Delete_Priv:
00651                             ptab[i] = (XrdAccPrivs)(ptab[i]|XrdAccPriv_Delete);
00652                             break;
00653                  case Insert_Priv: 
00654                             ptab[i] = (XrdAccPrivs)(ptab[i]|XrdAccPriv_Insert);
00655                             break;
00656                  case   Lock_Priv: 
00657                             ptab[i] = (XrdAccPrivs)(ptab[i]|XrdAccPriv_Lock);
00658                             break;
00659                  case Lookup_Priv: 
00660                             ptab[i] = (XrdAccPrivs)(ptab[i]|XrdAccPriv_Lookup);
00661                             break;
00662                  case Rename_Priv: 
00663                             ptab[i] = (XrdAccPrivs)(ptab[i]|XrdAccPriv_Rename);
00664                             break;
00665                  case   Read_Priv: 
00666                             ptab[i] = (XrdAccPrivs)(ptab[i]|XrdAccPriv_Read);
00667                             break;
00668                  case  Write_Priv: 
00669                             ptab[i] = (XrdAccPrivs)(ptab[i]|XrdAccPriv_Write);
00670                             break;
00671                  case    Neg_Priv: if (i) return 0; i++;   break;
00672                  default:                 return 0;
00673                 }
00674            privs++;
00675           }
00676      ctab.pprivs = ptab[0]; ctab.nprivs = ptab[1];
00677      return 1;
00678 }

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