/******************************************************************************/ /* */ /* X r d S e c s s s I D . c c */ /* */ /* (c) 2008 by the Board of Trustees of the Leland Stanford, Jr., University */ /* All Rights Reserved */ /* Produced by Andrew Hanushevsky for Stanford University under contract */ /* DE-AC02-76-SFO0515 with the Department of Energy */ /* */ /* This file is part of the XRootD software suite. */ /* */ /* XRootD is free software: you can redistribute it and/or modify it under */ /* the terms of the GNU Lesser General Public License as published by the */ /* Free Software Foundation, either version 3 of the License, or (at your */ /* option) any later version. */ /* */ /* XRootD is distributed in the hope that it will be useful, but WITHOUT */ /* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or */ /* FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public */ /* License for more details. */ /* */ /* You should have received a copy of the GNU Lesser General Public License */ /* along with XRootD in a file called COPYING.LESSER (LGPL license) and file */ /* COPYING (GPL license). If not, see . */ /* */ /* The copyright holder's institutional names and contributor's names may not */ /* be used to endorse or promote products derived from this software without */ /* specific prior written permission of the institution or contributor. */ /******************************************************************************/ #include #include #include #include #include #include "XrdSecsss/XrdSecsssID.hh" #include "XrdSecsss/XrdSecsssRR.hh" #include "XrdOuc/XrdOucPup.hh" #include "XrdOuc/XrdOucUtils.hh" #include "XrdSys/XrdSysHeaders.hh" /******************************************************************************/ /* D e f i n e s */ /******************************************************************************/ #define XRDSECSSSID "XrdSecsssID" #define XRDSECSSSENDO "XrdSecsssENDORSEMENT" XrdSysMutex XrdSecsssID::InitMutex; /******************************************************************************/ /* C o n s t r u c t o r */ /******************************************************************************/ XrdSecsssID::XrdSecsssID(authType aType, XrdSecEntity *idP) : defaultID(0) { static char buff[64]; union {unsigned long val; XrdSecsssID *myP;} p2i; // Check if we have initialized already. If so, indicate warning // InitMutex.Lock(); if (getenv(XRDSECSSSID)) {InitMutex.UnLock(); cerr <<"SecsssID: Already instantiated; new instance ineffective!" <iLen > Blen) {myMutex.UnLock(); return 0;} // Return the data // memcpy(Buff, fP->iData, fP->iLen); rc = fP->iLen; myMutex.UnLock(); return rc; } /******************************************************************************/ /* g e t O b j */ /******************************************************************************/ XrdSecsssID *XrdSecsssID::getObj(authType &aType, char **dID, int &dIDsz) { int freeIDP = 0; sssID *idP; char *eP, *xP; union {long long llval; long lval; XrdSecsssID *idP;} i2p; // Prevent changes // InitMutex.Lock(); // Convert to pointer // aType = idStatic; if ((eP = getenv(XRDSECSSSID)) && *eP) {if (sizeof(XrdSecsssID *) > 4) i2p.llval = strtoll(eP, &xP, 16); else i2p.lval = strtol (eP, &xP, 16); if (*xP) i2p.idP = 0; else aType = i2p.idP->myAuth; } else i2p.idP = 0; // Establish the default ID // if (!i2p.idP || !(idP = i2p.idP->defaultID)) {idP = genID(aType == idDynamic); freeIDP = 1;} // Copy out the default id to the caller // dIDsz = idP->iLen; *dID = (char *)malloc(dIDsz); memcpy(*dID, idP->iData, dIDsz); // Return result // InitMutex.UnLock(); if (freeIDP) free(idP); return i2p.idP; } /******************************************************************************/ /* R e g i s t e r */ /******************************************************************************/ int XrdSecsssID::Register(const char *lid, XrdSecEntity *eP, int doRep) { sssID *idP; int rc; int hOpt = (doRep ? Hash_replace : Hash_default) | Hash_dofree; // Check if we are simply deleting an entry // if (!eP) {myMutex.Lock(); Registry.Del(lid); myMutex.UnLock(); return 1;} // Generate an ID and add it to registry // if (!(idP = genID(eP))) return 0; myMutex.Lock(); rc = (Registry.Add(lid, idP, 0, XrdOucHash_Options(hOpt)) ? 0 : 1); myMutex.UnLock(); return rc; } /******************************************************************************/ /* P r i v a t e M e t h o d s */ /******************************************************************************/ /******************************************************************************/ /* g e n I D */ /******************************************************************************/ XrdSecsssID::sssID *XrdSecsssID::genID(int Secure) { XrdSecEntity myID("sss"); static const int pgSz = 256; char pBuff[pgSz], gBuff[pgSz]; // Use either our own uid/gid or a generic // myID.name = (Secure || XrdOucUtils:: UserName(geteuid(), pBuff, pgSz)) ? (char *)"nobody" : pBuff; myID.grps = (Secure || XrdOucUtils::GroupName(getegid(), gBuff, pgSz) == 0) ? (char *)"nogroup" : gBuff; if (getenv(XRDSECSSSENDO)) {myID.endorsements = getenv(XRDSECSSSENDO); } // Just return the sssID // return genID(&myID); } /******************************************************************************/ XrdSecsssID::sssID *XrdSecsssID::genID(XrdSecEntity *eP) { sssID *idP; char *bP; int tLen; // Calculate the length needed for the entity (4 bytes overhead for each item) // tLen = (eP->name ? strlen(eP->name) + 4 : 0) + (eP->vorg ? strlen(eP->vorg) + 4 : 0) + (eP->role ? strlen(eP->role) + 4 : 0) + (eP->grps ? strlen(eP->grps) + 4 : 0) + (eP->endorsements ? strlen(eP->endorsements) + 4 : 0); // If no identity information, return failure otherwise allocate a struct // if (!tLen || !(idP = (sssID *)malloc(tLen + sizeof(sssID)))) return 0; // Now stick each entry into the iData field // bP = idP->iData; if (eP->name) {*bP++ = XrdSecsssRR_Data::theName; XrdOucPup::Pack(&bP,eP->name);} if (eP->vorg) {*bP++ = XrdSecsssRR_Data::theVorg; XrdOucPup::Pack(&bP,eP->vorg);} if (eP->role) {*bP++ = XrdSecsssRR_Data::theRole; XrdOucPup::Pack(&bP,eP->role);} if (eP->grps) {*bP++ = XrdSecsssRR_Data::theGrps; XrdOucPup::Pack(&bP,eP->grps);} if (eP->endorsements) {*bP++ = XrdSecsssRR_Data::theEndo; XrdOucPup::Pack(&bP,eP->endorsements);} idP->iLen = bP - (idP->iData); // All done // return idP; }