def getCredentials( self, ignoreDefault = False ): if not self.__loadedChain: return S_ERROR( "No chain loaded" ) credDict = { 'subject' : self.__certList[0].get_subject().one_line(), 'issuer' : self.__certList[0].get_issuer().one_line(), 'secondsLeft' : self.getRemainingSecs()[ 'Value' ], 'isProxy' : self.__isProxy, 'isLimitedProxy' : self.__isProxy and self.__isLimitedProxy, 'validDN' : False, 'validGroup' : False, 'groupProperties' : [] } if self.__isProxy: credDict[ 'identity'] = self.__certList[ self.__firstProxyStep + 1 ].get_subject().one_line() retVal = Registry.getUsernameForDN( credDict[ 'identity' ] ) if retVal[ 'OK' ]: credDict[ 'username' ] = retVal[ 'Value' ] credDict[ 'validDN' ] = True retVal = self.getDIRACGroup( ignoreDefault = ignoreDefault ) if retVal[ 'OK' ]: diracGroup = retVal[ 'Value' ] credDict[ 'group' ] = diracGroup retVal = Registry.getGroupsForUser( credDict[ 'username' ] ) if retVal[ 'OK' ] and diracGroup in retVal[ 'Value' ]: credDict[ 'validGroup' ] = True credDict[ 'groupProperties' ] = Registry.getPropertiesForGroup( diracGroup ) else: retVal = Registry.getHostnameForDN( credDict['subject'] ) retVal[ 'group' ] = 'hosts' if retVal[ 'OK' ]: credDict[ 'hostname' ] = retVal[ 'Value' ] credDict[ 'validDN' ] = True credDict[ 'validGroup' ] = True return S_OK( credDict )
def findGenericPilotCredentials(vo=False, group=False, pilotDN='', pilotGroup=''): """ Looks into the Operations/<>/Pilot section of CS to find the pilot credentials. Then check if the user has a registered proxy in ProxyManager. if pilotDN or pilotGroup are specified, use them """ if not group and not vo: return S_ERROR("Need a group or a VO to determine the Generic pilot credentials") if not vo: vo = Registry.getVOForGroup(group) if not vo: return S_ERROR("Group %s does not have a VO associated" % group) opsHelper = Operations.Operations(vo=vo) if not pilotGroup: pilotGroup = opsHelper.getValue("Pilot/GenericPilotGroup", "") if not pilotDN: pilotDN = opsHelper.getValue("Pilot/GenericPilotDN", "") if not pilotDN: pilotUser = opsHelper.getValue("Pilot/GenericPilotUser", "") if pilotUser: result = Registry.getDNForUsername(pilotUser) if result['OK']: pilotDN = result['Value'][0] if pilotDN and pilotGroup: gLogger.verbose("Pilot credentials: %s@%s" % (pilotDN, pilotGroup)) result = gProxyManager.userHasProxy(pilotDN, pilotGroup, 86400) if not result['OK']: return S_ERROR("%s@%s has no proxy in ProxyManager") return S_OK((pilotDN, pilotGroup)) if pilotDN: return S_ERROR("DN %s does not have group %s" % (pilotDN, pilotGroup)) return S_ERROR("No generic proxy in the Proxy Manager with groups %s" % pilotGroup)
def completeDelegation(self, requestId, userDN, delegatedPem): """ Complete a delegation and store it in the db """ retVal = self.retrieveDelegationRequest(requestId, userDN) if not retVal['OK']: return retVal request = retVal['Value'] chain = X509Chain(keyObj=request.getPKey()) retVal = chain.loadChainFromString(delegatedPem) if not retVal['OK']: return retVal retVal = chain.isValidProxy(ignoreDefault=True) noGroupFlag = False if not retVal['OK']: if DErrno.cmpError(retVal, DErrno.ENOGROUP): noGroupFlag = True else: return retVal result = chain.isVOMS() if result['OK'] and result['Value']: return S_ERROR( "Proxies with VOMS extensions are not allowed to be uploaded") retVal = request.checkChain(chain) if not retVal['OK']: return retVal if not retVal['Value']: return S_ERROR("Received chain does not match request: %s" % retVal['Message']) retVal = chain.getDIRACGroup() if not retVal['OK']: return retVal userGroup = retVal['Value'] if not userGroup: userGroup = Registry.getDefaultUserGroup() retVal = Registry.getGroupsForDN(userDN) if not retVal['OK']: return retVal if not userGroup in retVal['Value']: return S_ERROR("%s group is not valid for %s" % (userGroup, userDN)) # For proxies without embedded DIRAC group only one default is allowed # Cleaning all the proxies for this DN if any before uploading the new one. if noGroupFlag: retVal = self.deleteProxy(userDN) if not retVal['OK']: return retVal retVal = self.storeProxy(userDN, userGroup, chain) if not retVal['OK']: return retVal retVal = self.deleteRequest(requestId) if not retVal['OK']: return retVal return S_OK()
def findGenericCloudCredentials(vo=False, group=False): """Get the cloud credentials to use for a specific VO and/or group.""" if not group and not vo: return S_ERROR( "Need a group or a VO to determine the Generic cloud credentials") if not vo: vo = Registry.getVOForGroup(group) if not vo: return S_ERROR("Group %s does not have a VO associated" % group) opsHelper = Operations.Operations(vo=vo) cloudGroup = opsHelper.getValue("Cloud/GenericCloudGroup", "") cloudDN = opsHelper.getValue("Cloud/GenericCloudDN", "") if not cloudDN: cloudUser = opsHelper.getValue("Cloud/GenericCloudUser", "") if cloudUser: result = Registry.getDNForUsername(cloudUser) if result["OK"]: cloudDN = result["Value"][0] else: return S_ERROR("Failed to find suitable CloudDN") if cloudDN and cloudGroup: gLogger.verbose("Cloud credentials from CS: %s@%s" % (cloudDN, cloudGroup)) result = gProxyManager.userHasProxy(cloudDN, cloudGroup, 86400) if not result["OK"]: return result return S_OK((cloudDN, cloudGroup)) return S_ERROR("Cloud credentials not found")
def addVOMSExtIfNeeded(self): addVOMS = self.__piParams.addVOMSExt or Registry.getGroupOption( self.__piParams.diracGroup, "AutoAddVOMS", False ) if not addVOMS: return S_OK() vomsAttr = Registry.getVOMSAttributeForGroup(self.__piParams.diracGroup) if not vomsAttr: return S_ERROR( "Requested adding a VOMS extension but no VOMS attribute defined for group %s" % self.__piParams.diracGroup ) result = VOMS.VOMS().setVOMSAttributes( self.__proxyGenerated, attribute=vomsAttr, vo=Registry.getVOForGroup(self.__piParams.diracGroup) ) if not result["OK"]: return S_ERROR( "Could not add VOMS extensions to the proxy\nFailed adding VOMS attribute: %s" % result["Message"] ) gLogger.notice("Added VOMS attribute %s" % vomsAttr) chain = result["Value"] chain.dumpAllToFile(self.__proxyGenerated) return S_OK()
def getUsername(self, credDict): """ Discover the username associated to the DN. It will check if the selected group is valid. The username will be included in the credentials dictionary. :type credDict: dictionary :param credDict: Credentials to check :return: Boolean specifying whether the username was found """ if self.KW_DN not in credDict: return True if self.KW_GROUP not in credDict: result = Registry.findDefaultGroupForDN(credDict[self.KW_DN]) if not result['OK']: return False credDict[self.KW_GROUP] = result['Value'] credDict[self.KW_PROPERTIES] = Registry.getPropertiesForGroup(credDict[self.KW_GROUP], []) usersInGroup = Registry.getUsersInGroup(credDict[self.KW_GROUP], []) if not usersInGroup: return False retVal = Registry.getUsernameForDN(credDict[self.KW_DN], usersInGroup) if retVal['OK']: credDict[self.KW_USERNAME] = retVal['Value'] return True return False
def addVOMSExtIfNeeded(self): addVOMS = self.__piParams.addVOMSExt or Registry.getGroupOption( self.__piParams.diracGroup, "AutoAddVOMS", False) if not addVOMS: return S_OK() vomsAttr = Registry.getVOMSAttributeForGroup( self.__piParams.diracGroup) if not vomsAttr: return S_ERROR( "Requested adding a VOMS extension but no VOMS attribute defined for group %s" % self.__piParams.diracGroup) resultVomsAttributes = VOMS.VOMS().setVOMSAttributes( self.__proxyGenerated, attribute=vomsAttr, vo=Registry.getVOMSVOForGroup(self.__piParams.diracGroup)) if not resultVomsAttributes['OK']: return S_ERROR( "Could not add VOMS extensions to the proxy\nFailed adding VOMS attribute: %s" % resultVomsAttributes['Message']) gLogger.notice("Added VOMS attribute %s" % vomsAttr) chain = resultVomsAttributes['Value'] result = chain.dumpAllToFile(self.__proxyGenerated) if not result["OK"]: return result return S_OK()
def getGroupsToUpload( self ): uploadGroups = [] if self.__piParams.uploadProxy or Registry.getGroupOption( self.__piParams.diracGroup, "AutoUploadProxy", False ): uploadGroups.append( self.__piParams.diracGroup ) if not self.__piParams.uploadPilot: if not Registry.getGroupOption( self.__piParams.diracGroup, "AutoUploadPilotProxy", False ): return uploadGroups issuerCert = self.getIssuerCert() resultUserDN = issuerCert.getSubjectDN() #pylint: disable=no-member if not resultUserDN['OK']: return resultUserDN userDN = resultUserDN[ 'Value' ] resultGroups = Registry.getGroupsForDN( userDN ) if not resultGroups[ 'OK' ]: gLogger.error( "No groups defined for DN %s" % userDN ) return [] availableGroups = resultGroups[ 'Value' ] for group in availableGroups: groupProps = Registry.getPropertiesForGroup( group ) if Properties.PILOT in groupProps or Properties.GENERIC_PILOT in groupProps: uploadGroups.append( group ) return uploadGroups
def getGroupsToUpload(self): uploadGroups = [] if self.__piParams.uploadProxy or Registry.getGroupOption( self.__piParams.diracGroup, "AutoUploadProxy", False): uploadGroups.append(self.__piParams.diracGroup) if not self.__piParams.uploadPilot: if not Registry.getGroupOption(self.__piParams.diracGroup, "AutoUploadPilotProxy", False): return uploadGroups issuerCert = self.getIssuerCert() resultUserDN = issuerCert.getSubjectDN() #pylint: disable=no-member if not resultUserDN['OK']: return resultUserDN userDN = resultUserDN['Value'] resultGroups = Registry.getGroupsForDN(userDN) if not resultGroups['OK']: gLogger.error("No groups defined for DN %s" % userDN) return [] availableGroups = resultGroups['Value'] for group in availableGroups: groupProps = Registry.getPropertiesForGroup(group) if Properties.PILOT in groupProps or Properties.GENERIC_PILOT in groupProps: uploadGroups.append(group) return uploadGroups
def export_getUsersTokensInfo(self, users: list): """Get the info about the user tokens in the database :param users: user names :return: S_OK(list) -- return list of tokens dictionaries """ tokensInfo = [] for user in users: # Find the user ID among his DNs result = Registry.getDNForUsername(user) if not result["OK"]: return result for dn in result["Value"]: uid = Registry.getIDFromDN(dn).get("Value") if uid: result = self.__tokenDB.getTokensByUserID(uid) if not result["OK"]: self.log.error(result["Message"]) else: for tokenDict in result["Value"]: if tokenDict not in tokensInfo: # The database does not contain a username, # as it is a unique user ID exclusively for DIRAC # and is not associated with a token. tokenDict["username"] = user tokensInfo.append(tokenDict) return S_OK(tokensInfo)
def __getPUSProxy(self, userDN, userGroup, requiredLifetime, requestedVOMSAttr=None): result = Registry.getGroupsForDN(userDN) if not result['OK']: return result validGroups = result['Value'] if not userGroup in validGroups: return S_ERROR('Invalid group %s for user' % userGroup) voName = Registry.getVOForGroup(userGroup) if not voName: return S_ERROR('Can not determine VO for group %s' % userGroup) retVal = self.__getVOMSAttribute(userGroup, requestedVOMSAttr) if not retVal['OK']: return retVal vomsAttribute = retVal['Value']['attribute'] vomsVO = retVal['Value']['VOMSVO'] puspServiceURL = Registry.getVOOption(voName, 'PUSPServiceURL') if not puspServiceURL: return S_ERROR('Can not determine PUSP service URL for VO %s' % voName) user = userDN.split(":")[-1] puspURL = "%s?voms=%s:%s&proxy-renewal=false&disable-voms-proxy=false" \ "&rfc-proxy=true&cn-label=user:%s" % ( puspServiceURL, vomsVO, vomsAttribute, user ) try: proxy = urllib.urlopen(puspURL).read() except Exception as e: return S_ERROR('Failed to get proxy from the PUSP server') chain = X509Chain() chain.loadChainFromString(proxy) chain.loadKeyFromString(proxy) result = chain.getCredentials() if not result['OK']: return S_ERROR('Failed to get a valid PUSP proxy') credDict = result['Value'] if credDict['identity'] != userDN: return S_ERROR( 'Requested DN does not match the obtained one in the PUSP proxy' ) timeLeft = credDict['secondsLeft'] result = chain.generateProxyToString(lifeTime=timeLeft, diracGroup=userGroup) if not result['OK']: return result proxyString = result['Value'] return S_OK((proxyString, timeLeft))
def sendExpirationNotifications( self ): result = self.__cleanExpNotifs() if not result[ 'OK' ]: return result cmd = "SELECT UserDN, UserGroup, LifeLimit FROM `ProxyDB_ExpNotifs`" result = self._query( cmd ) if not result[ 'OK' ]: return result notifDone = dict( [ ( ( row[0], row[1] ), row[2] ) for row in result[ 'Value' ] ] ) notifLimits = sorted( [ int( x ) for x in self.getCSOption( "NotificationTimes", ProxyDB.NOTIFICATION_TIMES ) ] ) sqlSel = "UserDN, UserGroup, TIMESTAMPDIFF( SECOND, UTC_TIMESTAMP(), ExpirationTime )" sqlCond = "TIMESTAMPDIFF( SECOND, UTC_TIMESTAMP(), ExpirationTime ) < %d" % max( notifLimits ) cmd = "SELECT %s FROM `ProxyDB_Proxies` WHERE %s" % ( sqlSel, sqlCond ) result = self._query( cmd ) if not result[ 'OK' ]: return result pilotProps = ( Properties.GENERIC_PILOT, Properties.PILOT ) data = result[ 'Value' ] sent = [] for row in data: userDN, group, lTime = row #If it's a pilot proxy, skip it if Registry.groupHasProperties( group, pilotProps ): continue #IF it dosn't hace the auto upload proxy, skip it if not Registry.getGroupOption( group, "AutoUploadProxy", False ): continue notKey = ( userDN, group ) for notifLimit in notifLimits: if notifLimit < lTime: #Not yet in this notification limit continue if notKey in notifDone and notifDone[ notKey ] <= notifLimit: #Already notified for this notification limit break if not self._notifyProxyAboutToExpire( userDN, group, lTime, notifLimit ): #Cannot send notification, retry later break try: sUserDN = self._escapeString( userDN )[ 'Value' ] sGroup = self._escapeString( group )[ 'Value' ] except KeyError: return S_ERROR( "OOPS" ) if notKey not in notifDone: values = "( %s, %s, %d, TIMESTAMPADD( SECOND, %s, UTC_TIMESTAMP() ) )" % ( sUserDN, sGroup, notifLimit, lTime ) cmd = "INSERT INTO `ProxyDB_ExpNotifs` ( UserDN, UserGroup, LifeLimit, ExpirationTime ) VALUES %s" % values result = self._update( cmd ) if not result[ 'OK' ]: gLogger.error( "Could not mark notification as sent", result[ 'Message' ] ) else: values = "LifeLimit = %d, ExpirationTime = TIMESTAMPADD( SECOND, %s, UTC_TIMESTAMP() )" % ( notifLimit, lTime ) cmd = "UPDATE `ProxyDB_ExpNotifs` SET %s WHERE UserDN = %s AND UserGroup = %s" % ( values, sUserDN, sGroup ) result = self._update( cmd ) if not result[ 'OK' ]: gLogger.error( "Could not mark notification as sent", result[ 'Message' ] ) sent.append( ( userDN, group, lTime ) ) notifDone[ notKey ] = notifLimit return S_OK( sent )
def findGenericPilotCredentials( vo = False, group = False ): if not group and not vo: return S_ERROR( "Need a group or a VO to determine the Generic pilot credentials" ) if not vo: vo = Registry.getVOForGroup( group ) if not vo: return S_ERROR( "Group %s does not have a VO associated" % group ) opsHelper = Operations.Operations( vo = vo ) pilotGroup = opsHelper.getValue( "Pilot/GenericPilotGroup", "" ) pilotDN = opsHelper.getValue( "Pilot/GenericPilotDN", "" ) if pilotDN and pilotGroup: gLogger.verbose( "Pilot credentials have been defined in the CS. Using %s@%s" % ( pilotDN, pilotGroup ) ) result = gProxyManager.userHasProxy( pilotDN, pilotGroup, 86400 ) if not result[ 'OK' ]: return S_ERROR( "%s@%s has no proxy uploaded to the ProxyManager" ) return S_OK( ( pilotDN, pilotGroup ) ) #Auto discover gLogger.verbose( "Pilot credentials are not defined. Autodiscovering..." ) if pilotGroup: pilotGroups = [ pilotGroup ] else: result = Registry.getGroupsWithProperty( Properties.GENERIC_PILOT ) if not result[ 'OK' ]: return result pilotGroups = [] groups = result[ 'Value' ] if not groups: return S_ERROR( "No group with %s property defined" % Properties.GENERIC_PILOT ) result = Registry.getGroupsForVO( vo ) if not result[ 'OK' ]: return result for voGroup in result[ 'Value' ]: if voGroup in groups: pilotGroups.append( voGroup ) if not pilotGroups: return S_ERROR( "No group for VO %s is a generic pilot group" % vo ) for pilotGroup in pilotGroups: DNs = Registry.getDNsInGroup( pilotGroup ) if not DNs: continue if pilotDN: if pilotDN not in DNs: continue result = gProxyManager.userHasProxy( pilotDN, pilotGroup, 86400 ) if result[ 'OK' ] and result[ 'Value' ]: gLogger.verbose( "Discovered pilot credentials are %s@%s" % ( pilotDN, pilotGroup ) ) return S_OK( ( pilotDN, pilotGroup ) ) else: for DN in DNs: result = gProxyManager.userHasProxy( DN, pilotGroup, 86400 ) if result[ 'OK' ] and result[ 'Value' ]: gLogger.verbose( "Discovered pilot credentials are %s@%s" % ( DN, pilotGroup ) ) return S_OK( ( DN, pilotGroup ) ) if pilotDN: return S_ERROR( "DN %s does not have group %s" % ( pilotDN, pilotGroups ) ) return S_ERROR( "No generic proxy in the Proxy Manager with groups %s" % pilotGroups )
def completeDelegation( self, requestId, userDN, delegatedPem ): """ Complete a delegation and store it in the db """ retVal = self.retrieveDelegationRequest( requestId, userDN ) if not retVal[ 'OK' ]: return retVal request = retVal[ 'Value' ] chain = X509Chain( keyObj = request.getPKey() ) retVal = chain.loadChainFromString( delegatedPem ) if not retVal[ 'OK' ]: return retVal retVal = chain.isValidProxy( ignoreDefault = True ) noGroupFlag = False if not retVal[ 'OK' ]: if DErrno.cmpError( retVal, DErrno.ENOGROUP ): noGroupFlag = True else: return retVal result = chain.isVOMS() if result[ 'OK' ] and result[ 'Value' ]: return S_ERROR( "Proxies with VOMS extensions are not allowed to be uploaded" ) retVal = request.checkChain( chain ) if not retVal[ 'OK' ]: return retVal if not retVal[ 'Value' ]: return S_ERROR( "Received chain does not match request: %s" % retVal[ 'Message' ] ) retVal = chain.getDIRACGroup() if not retVal[ 'OK' ]: return retVal userGroup = retVal[ 'Value' ] if not userGroup: userGroup = Registry.getDefaultUserGroup() retVal = Registry.getGroupsForDN( userDN ) if not retVal[ 'OK' ]: return retVal if not userGroup in retVal[ 'Value' ]: return S_ERROR( "%s group is not valid for %s" % ( userGroup, userDN ) ) # For proxies without embedded DIRAC group only one default is allowed # Cleaning all the proxies for this DN if any before uploading the new one. if noGroupFlag: retVal = self.deleteProxy( userDN ) if not retVal[ 'OK' ]: return retVal retVal = self.storeProxy( userDN, userGroup, chain ) if not retVal[ 'OK' ]: return retVal retVal = self.deleteRequest( requestId ) if not retVal[ 'OK' ]: return retVal return S_OK()
def findGenericPilotCredentials( vo = False, group = False ): if not group and not vo: return S_ERROR( "Need a group or a VO to determine the Generic pilot credentials" ) if not vo: vo = Registry.getVOForGroup( group ) if not vo: return S_ERROR( "Group %s does not have a VO associated" % group ) opsHelper = Operations.Operations( vo = vo ) pilotGroup = opsHelper.getValue( "Pilot/GenericPilotGroup", "" ) pilotDN = opsHelper.getValue( "Pilot/GenericPilotDN", "" ) if pilotDN and pilotGroup: gLogger.verbose( "Pilot credentials from CS: %s@%s" % ( pilotDN, pilotGroup ) ) result = gProxyManager.userHasProxy( pilotDN, pilotGroup, 86400 ) if not result[ 'OK' ]: return S_ERROR( "%s@%s has no proxy in ProxyManager" ) return S_OK( ( pilotDN, pilotGroup ) ) #Auto discover gLogger.verbose( "Pilot credentials are not defined. Autodiscovering..." ) if pilotGroup: pilotGroups = [ pilotGroup ] else: result = Registry.getGroupsWithProperty( Properties.GENERIC_PILOT ) if not result[ 'OK' ]: return result pilotGroups = [] groups = result[ 'Value' ] if not groups: return S_ERROR( "No group with %s property defined" % Properties.GENERIC_PILOT ) result = Registry.getGroupsForVO( vo ) if not result[ 'OK' ]: return result for voGroup in result[ 'Value' ]: if voGroup in groups: pilotGroups.append( voGroup ) if not pilotGroups: return S_ERROR( "No generic pilot group for VO %s" % vo ) for pilotGroup in pilotGroups: DNs = Registry.getDNsInGroup( pilotGroup ) if not DNs: continue if pilotDN: if pilotDN not in DNs: continue result = gProxyManager.userHasProxy( pilotDN, pilotGroup, 86400 ) if result[ 'OK' ] and result[ 'Value' ]: gLogger.verbose( "Discovered pilot credentials: %s@%s" % ( pilotDN, pilotGroup ) ) return S_OK( ( pilotDN, pilotGroup ) ) else: for DN in DNs: result = gProxyManager.userHasProxy( DN, pilotGroup, 86400 ) if result[ 'OK' ] and result[ 'Value' ]: gLogger.verbose( "Discovered pilot credentials: %s@%s" % ( DN, pilotGroup ) ) return S_OK( ( DN, pilotGroup ) ) if pilotDN: return S_ERROR( "DN %s does not have group %s" % ( pilotDN, pilotGroups ) ) return S_ERROR( "No generic proxy in the Proxy Manager with groups %s" % pilotGroups )
def __getVOMSAttribute( self, userGroup, requiredVOMSAttribute = False ): if requiredVOMSAttribute: return S_OK( { 'attribute' : requiredVOMSAttribute, 'VOMSVO' : Registry.getVOMSVOForGroup( userGroup ) } ) csVOMSMapping = Registry.getVOMSAttributeForGroup( userGroup ) if not csVOMSMapping: return S_ERROR( "No mapping defined for group %s in the CS" % userGroup ) return S_OK( { 'attribute' : csVOMSMapping, 'VOMSVO' : Registry.getVOMSVOForGroup( userGroup ) } )
def getVOfromProxyGroup(): """ Return the VO associated to the group in the proxy """ voName = Registry.getVOForGroup("NoneExistingGroup") ret = getProxyInfo(disableVOMS=True) if not ret["OK"]: return S_OK(voName) if "group" in ret["Value"]: voName = Registry.getVOForGroup(ret["Value"]["group"]) return S_OK(voName)
def __setupManagerProxies(self): """setup grid proxy for all defined managers""" oHelper = Operations() shifters = oHelper.getSections("Shifter") if not shifters["OK"]: return shifters shifters = shifters["Value"] for shifter in shifters: shifterDict = oHelper.getOptionsDict("Shifter/%s" % shifter) if not shifterDict["OK"]: self.log.error("Cannot get options dict for shifter", "%s: %s" % (shifter, shifterDict["Message"])) continue userName = shifterDict["Value"].get("User", "") userGroup = shifterDict["Value"].get("Group", "") userDN = Registry.getDNForUsername(userName) if not userDN["OK"]: self.log.error("Cannot get DN For Username", "%s: %s" % (userName, userDN["Message"])) continue userDN = userDN["Value"][0] vomsAttr = Registry.getVOMSAttributeForGroup(userGroup) if vomsAttr: self.log.debug( "getting VOMS [%s] proxy for shifter %s@%s (%s)" % (vomsAttr, userName, userGroup, userDN)) getProxy = gProxyManager.downloadVOMSProxyToFile( userDN, userGroup, requiredTimeLeft=1200, cacheTime=4 * 43200) else: self.log.debug("getting proxy for shifter %s@%s (%s)" % (userName, userGroup, userDN)) getProxy = gProxyManager.downloadProxyToFile( userDN, userGroup, requiredTimeLeft=1200, cacheTime=4 * 43200) if not getProxy["OK"]: return S_ERROR("unable to setup shifter proxy for %s: %s" % (shifter, getProxy["Message"])) chain = getProxy["chain"] fileName = getProxy["Value"] self.log.debug("got %s: %s %s" % (shifter, userName, userGroup)) self.__managersDict[shifter] = { "ShifterDN": userDN, "ShifterName": userName, "ShifterGroup": userGroup, "Chain": chain, "ProxyFile": fileName, } return S_OK()
def getVOfromProxyGroup(): """ Return the VO associated to the group in the proxy """ voName = Registry.getVOForGroup( 'NoneExistingGroup' ) ret = getProxyInfo( disableVOMS = True ) if not ret['OK']: return S_OK( voName ) if 'group' in ret['Value']: voName = Registry.getVOForGroup( ret['Value']['group'] ) return S_OK( voName )
def __getPUSProxy( self, userDN, userGroup, requiredLifetime, requestedVOMSAttr = None ): result = Registry.getGroupsForDN( userDN ) if not result['OK']: return result validGroups = result['Value'] if not userGroup in validGroups: return S_ERROR( 'Invalid group %s for user' % userGroup ) voName = Registry.getVOForGroup( userGroup ) if not voName: return S_ERROR( 'Can not determine VO for group %s' % userGroup ) retVal = self.__getVOMSAttribute( userGroup, requestedVOMSAttr ) if not retVal[ 'OK' ]: return retVal vomsAttribute = retVal[ 'Value' ][ 'attribute' ] vomsVO = retVal[ 'Value' ][ 'VOMSVO' ] puspServiceURL = Registry.getVOOption( voName, 'PUSPServiceURL' ) if not puspServiceURL: return S_ERROR( 'Can not determine PUSP service URL for VO %s' % voName ) user = userDN.split(":")[-1] puspURL = "%s?voms=%s:%s&proxy-renewal=false&disable-voms-proxy=false" \ "&rfc-proxy=true&cn-label=user:%s" % ( puspServiceURL, vomsVO, vomsAttribute, user ) try: proxy = urllib.urlopen( puspURL ).read() except Exception as e: return S_ERROR( 'Failed to get proxy from the PUSP server' ) chain = X509Chain() chain.loadChainFromString( proxy ) chain.loadKeyFromString( proxy ) result = chain.getCredentials() if not result['OK']: return S_ERROR( 'Failed to get a valid PUSP proxy' ) credDict = result['Value'] if credDict['identity'] != userDN: return S_ERROR( 'Requested DN does not match the obtained one in the PUSP proxy' ) timeLeft = credDict['secondsLeft'] result = chain.generateProxyToString( lifeTime = timeLeft, diracGroup = userGroup ) if not result['OK']: return result proxyString = result['Value'] return S_OK( ( proxyString, timeLeft ) )
def getShifterProxy(shifterType, fileName=False): """ This method returns a shifter's proxy :param str shifterType: ProductionManager / DataManager... :param str fileName: file name :return: S_OK(dict)/S_ERROR() """ if fileName: mkDir(os.path.dirname(fileName)) opsHelper = Operations() userName = opsHelper.getValue(cfgPath('Shifter', shifterType, 'User'), '') if not userName: return S_ERROR("No shifter User defined for %s" % shifterType) result = Registry.getDNForUsername(userName) if not result['OK']: return result userDN = result['Value'][0] result = Registry.findDefaultGroupForDN(userDN) if not result['OK']: return result defaultGroup = result['Value'] userGroup = opsHelper.getValue(cfgPath('Shifter', shifterType, 'Group'), defaultGroup) vomsAttr = Registry.getVOMSAttributeForGroup(userGroup) if vomsAttr: gLogger.info("Getting VOMS [%s] proxy for shifter %s@%s (%s)" % (vomsAttr, userName, userGroup, userDN)) result = gProxyManager.downloadVOMSProxyToFile(userDN, userGroup, filePath=fileName, requiredTimeLeft=86400, cacheTime=86400) else: gLogger.info("Getting proxy for shifter %s@%s (%s)" % (userName, userGroup, userDN)) result = gProxyManager.downloadProxyToFile(userDN, userGroup, filePath=fileName, requiredTimeLeft=86400, cacheTime=86400) if not result['OK']: return result chain = result['chain'] fileName = result['Value'] return S_OK({ 'DN': userDN, 'username': userName, 'group': userGroup, 'chain': chain, 'proxyFile': fileName })
def completeDelegation(self, requestId, userDN, delegatedPem): """ Complete a delegation and store it in the db """ retVal = self.retrieveDelegationRequest(requestId, userDN) if not retVal['OK']: return retVal request = retVal['Value'] chain = X509Chain(keyObj=request.getPKey()) retVal = chain.loadChainFromString(delegatedPem) if not retVal['OK']: return retVal retVal = chain.isValidProxy() if not retVal['OK']: return retVal if not retVal['Value']: return S_ERROR("Chain received is not a valid proxy: %s" % retVal['Message']) retVal = request.checkChain(chain) if not retVal['OK']: return retVal if not retVal['Value']: return S_ERROR("Received chain does not match request: %s" % retVal['Message']) retVal = chain.getDIRACGroup() if not retVal['OK']: return retVal userGroup = retVal['Value'] if not userGroup: userGroup = Registry.getDefaultUserGroup() retVal = Registry.getGroupsForDN(userDN) if not retVal['OK']: return retVal if not userGroup in retVal['Value']: return S_ERROR("%s group is not valid for %s" % (userGroup, userDN)) retVal = self.__checkVOMSisAlignedWithGroup(userGroup, chain) if not retVal['OK']: return retVal retVal = self.storeProxy(userDN, userGroup, chain) if not retVal['OK']: return retVal retVal = self.deleteRequest(requestId) if not retVal['OK']: return retVal return S_OK()
def completeDelegation(self, requestId, userDN, delegatedPem): """ Complete a delegation and store it in the db """ retVal = self.retrieveDelegationRequest(requestId, userDN) if not retVal['OK']: return retVal request = retVal['Value'] chain = X509Chain(keyObj=request.getPKey()) retVal = chain.loadChainFromString(delegatedPem) if not retVal['OK']: return retVal retVal = chain.isValidProxy(ignoreDefault=True) if not retVal['OK']: return retVal result = chain.isVOMS() if result['OK'] and result['Value']: return S_ERROR( "Proxies with VOMS extensions are not allowed to be uploaded") retVal = request.checkChain(chain) if not retVal['OK']: return retVal if not retVal['Value']: return S_ERROR("Received chain does not match request: %s" % retVal['Message']) retVal = chain.getDIRACGroup() if not retVal['OK']: return retVal userGroup = retVal['Value'] if not userGroup: userGroup = Registry.getDefaultUserGroup() retVal = Registry.getGroupsForDN(userDN) if not retVal['OK']: return retVal if not userGroup in retVal['Value']: return S_ERROR("%s group is not valid for %s" % (userGroup, userDN)) retVal = self.storeProxy(userDN, userGroup, chain) if not retVal['OK']: return retVal retVal = self.deleteRequest(requestId) if not retVal['OK']: return retVal return S_OK()
def completeDelegation( self, requestId, userDN, delegatedPem ): """ Complete a delegation and store it in the db """ retVal = self.retrieveDelegationRequest( requestId, userDN ) if not retVal[ 'OK' ]: return retVal request = retVal[ 'Value' ] chain = X509Chain( keyObj = request.getPKey() ) retVal = chain.loadChainFromString( delegatedPem ) if not retVal[ 'OK' ]: return retVal retVal = chain.isValidProxy() if not retVal[ 'OK' ]: return retVal if not retVal[ 'Value' ]: return S_ERROR( "Chain received is not a valid proxy: %s" % retVal[ 'Message' ] ) retVal = request.checkChain( chain ) if not retVal[ 'OK' ]: return retVal if not retVal[ 'Value' ]: return S_ERROR( "Received chain does not match request: %s" % retVal[ 'Message' ] ) retVal = chain.getDIRACGroup() if not retVal[ 'OK' ]: return retVal userGroup = retVal[ 'Value' ] if not userGroup: userGroup = Registry.getDefaultUserGroup() retVal = Registry.getGroupsForDN( userDN ) if not retVal[ 'OK' ]: return retVal if not userGroup in retVal[ 'Value' ]: return S_ERROR( "%s group is not valid for %s" % ( userGroup, userDN ) ) retVal = self.__checkVOMSisAlignedWithGroup( userGroup, chain ) if not retVal[ 'OK' ]: return retVal retVal = self.storeProxy( userDN, userGroup, chain ) if not retVal[ 'OK' ]: return retVal retVal = self.deleteRequest( requestId ) if not retVal[ 'OK' ]: return retVal return S_OK()
def getPilotProxyFromVOMSGroup(self, userDN, vomsAttr, requiredTimeLeft=43200, proxyToConnect=None): """ Download a pilot proxy with VOMS extensions depending on the group :param basestring userDN: user DN :param basestring vomsAttr: VOMS attribute :param int requiredTimeLeft: required proxy live time in a seconds :param X509Chain proxyToConnect: proxy as a chain :return: S_OK(X509Chain)/S_ERROR() """ groups = Registry.getGroupsWithVOMSAttribute(vomsAttr) if not groups: return S_ERROR("No group found that has %s as voms attrs" % vomsAttr) for userGroup in groups: result = self.downloadVOMSProxy(userDN, userGroup, limited=False, requiredTimeLeft=requiredTimeLeft, requiredVOMSAttribute=vomsAttr, proxyToConnect=proxyToConnect) if result['OK']: return result return result
def __addUserNameToTable(self, tableName): result = self._update( "ALTER TABLE `%s` ADD COLUMN UserName VARCHAR(64) NOT NULL" % tableName) if not result['OK']: return result result = self._query("SELECT DISTINCT UserName, UserDN FROM `%s`" % tableName) if not result['OK']: return result data = result['Value'] for userName, userDN in data: if not userName: result = Registry.getUsernameForDN(userDN) if not result['OK']: self.log.error("Could not retrieve username for DN %s" % userDN) continue userName = result['Value'] result = self._escapeString(userName) if not result['OK']: self.log.error("Could not escape username %s" % userName) continue userName = result['Value'] result = self._update( "UPDATE `%s` SET UserName=%s WHERE UserDN='%s'" % (tableName, userName, userDN)) if not result['OK']: self.log.error("Could update username for DN %s: %s" % (userDN, result['Message'])) continue self.log.info("UserDN %s has user %s" % (userDN, userName)) return S_OK()
def getPilotProxyFromDIRACGroup(self, userDN, userGroup, requiredTimeLeft=43200, proxyToConnect=None): """ Download a pilot proxy with VOMS extensions depending on the group :param basestring userDN: user DN :param basestring userGroup: user group :param int requiredTimeLeft: required proxy live time in a seconds :param X509Chain proxyToConnect: proxy as a chain :return: S_OK(X509Chain)/S_ERROR() """ # Assign VOMS attribute vomsAttr = Registry.getVOMSAttributeForGroup(userGroup) if not vomsAttr: gLogger.verbose( "No voms attribute assigned to group %s when requested pilot proxy" % userGroup) return self.downloadProxy(userDN, userGroup, limited=False, requiredTimeLeft=requiredTimeLeft, proxyToConnect=proxyToConnect) else: return self.downloadVOMSProxy(userDN, userGroup, limited=False, requiredTimeLeft=requiredTimeLeft, requiredVOMSAttribute=vomsAttr, proxyToConnect=proxyToConnect)
def __filterEntitiesByRequester(self, entitiesList, entitiesSetup, requesterName, requesterGroup): """ Given a list of entities and a requester, return the ones that the requester is allowed to modify """ sqlCond = [ "s.OwnerId=o.OwnerId", "s.SBId=e.SBId", "e.EntitySetup=%s" % entitiesSetup ] requesterProps = Registry.getPropertiesForEntity(requesterGroup, name=requesterName) if Properties.JOB_ADMINISTRATOR in requesterProps: # Do nothing, just ensure it doesn't fit in the other cases pass elif Properties.JOB_SHARING in requesterProps: sqlCond.append("o.OwnerGroup='%s'" % requesterGroup) elif Properties.NORMAL_USER in requesterProps: sqlCond.append("o.OwnerGroup='%s'" % requesterGroup) sqlCond.append("o.Owner='%s'" % requesterName) else: return S_ERROR("Not authorized to access sandbox") for i in range(len(entitiesList)): entitiesList[i] = self._escapeString(entitiesList[i])['Value'] if len(entitiesList) == 1: sqlCond.append("e.EntityId = %s" % entitiesList[0]) else: sqlCond.append("e.EntityId in ( %s )" % ", ".join(entitiesList)) sqlCmd = "SELECT DISTINCT e.EntityId FROM `sb_EntityMapping` e, `sb_SandBoxes` s, `sb_Owners` o WHERE" sqlCmd = "%s %s" % (sqlCmd, " AND ".join(sqlCond)) result = self._query(sqlCmd) if not result['OK']: return result return S_OK([row[0] for row in result['Value']])
def getSandboxesAssignedToEntity(self, entityId, entitySetup, requesterName, requesterGroup): """ Get the sandboxes and the type of assignation to the jobId """ sqlTables = ["`sb_SandBoxes` s", "`sb_EntityMapping` e"] sqlCond = [ "s.SBId = e.SBId", "e.EntityId = %s" % self._escapeString(entityId)['Value'], "e.EntitySetup = %s" % self._escapeString(entitySetup)['Value'] ] requesterProps = Registry.getPropertiesForEntity(requesterGroup, name=requesterName) if Properties.JOB_ADMINISTRATOR in requesterProps or Properties.JOB_MONITOR in requesterProps: # Do nothing, just ensure it doesn't fit in the other cases pass elif Properties.JOB_SHARING in requesterProps: sqlTables.append("`sb_Owners` o") sqlCond.append("o.OwnerGroup='%s'" % requesterGroup) sqlCond.append("s.OwnerId=o.OwnerId") elif Properties.NORMAL_USER in requesterProps: sqlTables.append("`sb_Owners` o") sqlCond.append("o.OwnerGroup='%s'" % requesterGroup) sqlCond.append("o.Owner='%s'" % requesterName) sqlCond.append("s.OwnerId=o.OwnerId") else: return S_ERROR("Not authorized to access sandbox") sqlCmd = "SELECT DISTINCT s.SEName, s.SEPFN, e.Type FROM %s WHERE %s" % ( ", ".join(sqlTables), " AND ".join(sqlCond)) return self._query(sqlCmd)
def addVomsExt( self, proxy ): retVal = self.getEnv( "group_name" ) if not retVal[ "OK" ]: raise Exception( result[ "Message" ] ) group = retVal[ "Value" ] vomsAttr = Registry.getVOMSAttributeForGroup( group ) if not vomsAttr: raise Exception( "Requested adding a VOMS extension but no VOMS attribute defined for group %s" % group ) result = VOMS.VOMS( ).setVOMSAttributes( proxy, attribute = vomsAttr, vo = Registry.getVOForGroup( group )) if not result[ 'OK' ]: raise Exception( "Could not add VOMS extensions to the proxy\nFailed adding VOMS attribute: %s" % result[ 'Message' ] ) chain = result[ 'Value' ] chain.dumpAllToFile( proxy )
def __processCredentials( self ): """ Extract the user credentials based on the certificate or what comes from the balancer """ self.__credDict = {} #NGINX if Conf.balancer() == "nginx": headers = self.request.headers if headers[ 'X-Scheme' ] == "https" and headers[ 'X-Ssl_client_verify' ] == 'SUCCESS': DN = headers[ 'X-Ssl_client_s_dn' ] self.__credDict[ 'subject' ] = DN self.__credDict[ 'issuer' ] = headers[ 'X-Ssl_client_i_dn' ] result = Registry.getUsernameForDN( DN ) if not result[ 'OK' ]: self.__credDict[ 'validDN' ] = False else: self.__credDict[ 'validDN' ] = True self.__credDict[ 'username' ] = result[ 'Value' ] return #TORNADO if not self.request.protocol == "https": return derCert = self.request.get_ssl_certificate( binary_form = True ) if not derCert: return pemCert = ssl.DER_cert_to_PEM_cert( derCert ) chain = X509Chain() chain.loadChainFromString( pemCert ) result = chain.getCredentials() if not result[ 'OK' ]: self.log.error( "Could not get client credentials %s" % result[ 'Message' ] ) return self.__credDict = result[ 'Value' ]
def getPayloadProxyFromVOMSGroup(self, userDN, vomsAttr, token, requiredTimeLeft, proxyToConnect=None): """ Download a payload proxy with VOMS extensions depending on the VOMS attr :param basestring userDN: user DN :param basestring vomsAttr: VOMS attribute :param basestring token: valid token to get a proxy :param int requiredTimeLeft: required proxy live time in a seconds :param X509Chain proxyToConnect: proxy as a chain :return: S_OK(X509Chain)/S_ERROR() """ groups = Registry.getGroupsWithVOMSAttribute(vomsAttr) if not groups: return S_ERROR("No group found that has %s as voms attrs" % vomsAttr) userGroup = groups[0] return self.downloadVOMSProxy(userDN, userGroup, limited=True, requiredTimeLeft=requiredTimeLeft, requiredVOMSAttribute=vomsAttr, proxyToConnect=proxyToConnect, token=token)
def __addUserNameToTable( self, tableName ): result = self._update( "ALTER TABLE `%s` ADD COLUMN UserName VARCHAR(64) NOT NULL" % tableName ) if not result[ 'OK' ]: return result result = self._query( "SELECT DISTINCT UserName, UserDN FROM `%s`" % tableName ) if not result[ 'OK' ]: return result data = result[ 'Value' ] for userName, userDN in data: if not userName: result = Registry.getUsernameForDN( userDN ) if not result[ 'OK' ]: self.log.error( "Could not retrieve username for DN %s" % userDN ) continue userName = result[ 'Value' ] result = self._escapeString( userName ) if not result[ 'OK' ]: self.log.error( "Could not escape username %s" % userName ) continue userName = result[ 'Value' ] result = self._update( "UPDATE `%s` SET UserName=%s WHERE UserDN='%s'" % ( tableName, userName, userDN ) ) if not result[ 'OK' ]: self.log.error( "Could update username for DN %s: %s" % ( userDN, result[ 'Message' ] ) ) continue self.log.info( "UserDN %s has user %s" % ( userDN, userName ) ) return S_OK()
def addDataset(self, name, datasetDict, numericid): """Pretty print of the dataset ls output""" perm = datasetDict["Mode"] date = datasetDict["ModificationDate"] size = datasetDict["TotalSize"] if "Owner" in datasetDict: uname = datasetDict["Owner"] elif "OwnerDN" in datasetDict: result = Registry.getUsernameForDN(datasetDict["OwnerDN"]) if result["OK"]: uname = result["Value"] else: uname = "unknown" else: uname = "unknown" if numericid: uname = str(datasetDict["UID"]) gname = "unknown" if "OwnerGroup" in datasetDict: gname = datasetDict["OwnerGroup"] if numericid: gname = str(datasetDict["GID"]) numberOfFiles = datasetDict["NumberOfFiles"] self.entries.append(("s" + self.__getModeString(perm), numberOfFiles, uname, gname, size, date, name))
def __executeClient(self, host, method, *parms, **kwargs): """Execute RPC method on a given host""" hostName = Registry.getHostOption(host, "Host", host) client = SystemAdministratorClient(hostName, **self.__kwargs) result = getattr(client, method)(*parms, **kwargs) result["Host"] = host return result
def _addPilotsAccountingReport(self, pilotsData): """ fill accounting data """ for pRef in pilotsData: pData = pilotsData[pRef] pA = PilotAccounting() pA.setEndTime(pData['LastUpdateTime']) pA.setStartTime(pData['SubmissionTime']) retVal = Registry.getUsernameForDN(pData['OwnerDN']) if not retVal['OK']: userName = '******' self.log.error("Can't determine username for dn:", pData['OwnerDN']) else: userName = retVal['Value'] pA.setValueByKey('User', userName) pA.setValueByKey('UserGroup', pData['OwnerGroup']) result = getCESiteMapping(pData['DestinationSite']) if result['OK'] and pData['DestinationSite'] in result['Value']: pA.setValueByKey('Site', result['Value'][pData['DestinationSite']].strip()) else: pA.setValueByKey('Site', 'Unknown') pA.setValueByKey('GridCE', pData['DestinationSite']) pA.setValueByKey('GridMiddleware', pData['GridType']) pA.setValueByKey('GridResourceBroker', pData['Broker']) pA.setValueByKey('GridStatus', pData['Status']) if 'Jobs' not in pData: pA.setValueByKey('Jobs', 0) else: pA.setValueByKey('Jobs', len(pData['Jobs'])) self.log.verbose("Added accounting record for pilot %s" % pData['PilotID']) retVal = gDataStoreClient.addRegister(pA) if not retVal['OK']: return retVal return S_OK()
def export_requestDelegationUpload( self, requestedUploadTime, userGroup ): """ Request a delegation. Send a delegation request to client """ credDict = self.getRemoteCredentials() userDN = credDict[ 'DN' ] userName = credDict[ 'username' ] if not userGroup: userGroup = credDict[ 'group' ] retVal = Registry.getGroupsForUser( credDict[ 'username' ] ) if not retVal[ 'OK' ]: return retVal groupsAvailable = retVal[ 'Value' ] if userGroup not in groupsAvailable: return S_ERROR( "%s is not a valid group for user %s" % ( userGroup, userName ) ) clientChain = credDict[ 'x509Chain' ] clientSecs = clientChain.getIssuerCert()[ 'Value' ].getRemainingSecs()[ 'Value' ] requestedUploadTime = min( requestedUploadTime, clientSecs ) retVal = self.__proxyDB.getRemainingTime( userDN, userGroup ) if not retVal[ 'OK' ]: return retVal remainingSecs = retVal[ 'Value' ] # If we have a proxy longer than the one uploading it's not needed # ten minute margin to compensate just in case if remainingSecs >= requestedUploadTime - 600: gLogger.info( "Upload request not necessary by %s:%s" % ( userName, userGroup ) ) return self.__addKnownUserProxiesInfo( S_OK() ) result = self.__proxyDB.generateDelegationRequest( credDict[ 'x509Chain' ], userDN ) if result[ 'OK' ]: gLogger.info( "Upload request by %s:%s given id %s" % ( userName, userGroup, result['Value']['id'] ) ) else: gLogger.error( "Upload request failed", "by %s:%s : %s" % ( userName, userGroup, result['Message'] ) ) return result
def __generateUserProxiesInfo(self): """ Generate information dict about user proxies :return: dict """ proxiesInfo = {} credDict = self.getRemoteCredentials() result = Registry.getDNForUsername(credDict['username']) if not result['OK']: return result selDict = {'UserDN': result['Value']} result = self.__proxyDB.getProxiesContent(selDict, {}) if not result['OK']: return result contents = result['Value'] userDNIndex = contents['ParameterNames'].index("UserDN") userGroupIndex = contents['ParameterNames'].index("UserGroup") expirationIndex = contents['ParameterNames'].index("ExpirationTime") for record in contents['Records']: userDN = record[userDNIndex] if userDN not in proxiesInfo: proxiesInfo[userDN] = {} userGroup = record[userGroupIndex] proxiesInfo[userDN][userGroup] = record[expirationIndex] return proxiesInfo
def __discoverExtraCredentials(self): """ Add extra credentials informations. * self.__extraCredentials -> if KW_EXTRA_CREDENTIALS in kwargs, we set it -> Otherwise, if we use the server certificate, we set it to VAL_EXTRA_CREDENTIALS_HOST -> If we have a delegation (see bellow), we set it to (delegatedDN, delegatedGroup) -> otherwise it is an empty string * delegation: -> if KW_DELEGATED_DN in kwargs, or delegatedDN in threadConfig, put in in self.kwargs -> if KW_DELEGATED_GROUP in kwargs or delegatedGroup in threadConfig, put it in self.kwargs -> If we have a delegated DN but not group, we find the corresponding group in the CS :return: S_OK()/S_ERROR() """ # which extra credentials to use? self.__extraCredentials = self.VAL_EXTRA_CREDENTIALS_HOST if self.__useCertificates else "" if self.KW_EXTRA_CREDENTIALS in self.kwargs: self.__extraCredentials = self.kwargs[self.KW_EXTRA_CREDENTIALS] # Are we delegating something? delegatedDN = self.kwargs.get(self.KW_DELEGATED_DN) or self.__threadConfig.getDN() delegatedGroup = self.kwargs.get(self.KW_DELEGATED_GROUP) or self.__threadConfig.getGroup() if delegatedDN: self.kwargs[self.KW_DELEGATED_DN] = delegatedDN if not delegatedGroup: result = Registry.findDefaultGroupForDN(delegatedDN) if not result['OK']: return result delegatedGroup = result['Value'] self.kwargs[self.KW_DELEGATED_GROUP] = delegatedGroup self.__extraCredentials = (delegatedDN, delegatedGroup) return S_OK()
def addVOMSExtIfNeeded( self ): addVOMS = Registry.getGroupOption( self.__piParams.diracGroup, "AutoAddVOMS", self.__piParams.addVOMSExt ) if not addVOMS: return vomsAttr = Registry.getVOMSAttributeForGroup( self.__piParams.diracGroup ) if not vomsAttr: gLogger.error( "Requested adding a VOMS extension but no VOMS attribute defined for group %s" % self.__piParams.diracGroup ) return result = VOMS.VOMS().setVOMSAttributes( vomsAttr, vo = Registry.getVOForGroup( self.__piParams.diracGroup ) ) if not result[ 'OK' ]: gLogger.error( "Failed adding VOMS attribute:", result[ 'Message' ] ) return False else: gLogger.notice( "Added VOMS attribute %s" % vomsAttr )
def export_requestDelegationUpload(self, requestedUploadTime, userGroup): """ Request a delegation. Send a delegation request to client """ credDict = self.getRemoteCredentials() userDN = credDict['DN'] userName = credDict['username'] if not userGroup: userGroup = credDict['group'] retVal = Registry.getGroupsForUser(credDict['username']) if not retVal['OK']: return retVal groupsAvailable = retVal['Value'] if userGroup not in groupsAvailable: return S_ERROR("%s is not a valid group for user %s" % (userGroup, userName)) clientChain = credDict['x509Chain'] clientSecs = clientChain.getIssuerCert()['Value'].getRemainingSecs( )['Value'] requestedUploadTime = min(requestedUploadTime, clientSecs) # FIXME: this is useless now... result = self.__proxyDB.generateDelegationRequest( credDict['x509Chain'], userDN) if result['OK']: gLogger.info("Upload request by %s:%s given id %s" % (userName, userGroup, result['Value']['id'])) else: gLogger.error( "Upload request failed", "by %s:%s : %s" % (userName, userGroup, result['Message'])) return result
def __init__( self, **kwargs ): """ Constructor """ if 'hosts' in kwargs: self.__hosts = kwargs['hosts'] del kwargs['hosts'] else: result = Registry.getHosts() if result['OK']: self.__hosts = result['Value'] else: self.__hosts = [] # Excluded hosts if 'exclude' in kwargs: self.__hosts = list ( set( self.__hosts ) - set( kwargs[ 'exclude' ] ) ) # Ping the hosts to remove those that don't have a SystemAdministrator service sysAdminHosts = [] for host in self.__hosts: client = SystemAdministratorClient( host ) result = client.ping() if result[ 'OK' ]: sysAdminHosts.append( host ) self.__hosts = sysAdminHosts self.__kwargs = dict( kwargs ) self.__pool = ThreadPool( len( self.__hosts ) ) self.__resultDict = {}
def addNotificationForUser(self, user, message, lifetime=0, deferToMail=1): if user not in Registry.getAllUsers(): return S_ERROR("%s is an unknown user" % user) self.log.info("Adding a notification for user %s (msg is %s chars)" % (user, len(message))) result = self._escapeString(user) if not result["OK"]: return result user = result["Value"] result = self._escapeString(message) if not result["OK"]: return result message = result["Value"] sqlFields = ["User", "Message", "Timestamp"] sqlValues = [user, message, "UTC_TIMESTAMP()"] if not deferToMail: sqlFields.append("DeferToMail") sqlValues.append("0") if lifetime: sqlFields.append("Expiration") sqlValues.append("TIMESTAMPADD( SECOND, %d, UTC_TIMESTAMP() )" % int(lifetime)) sqlInsert = "INSERT INTO `ntf_Notifications` (%s) VALUES (%s) " % (",".join(sqlFields), ",".join(sqlValues)) result = self._update(sqlInsert) if not result["OK"]: return result return S_OK(result["lastRowId"])
def completeDelegation( self, requestId, userDN, delegatedPem ): """ Complete a delegation and store it in the db """ retVal = self.retrieveDelegationRequest( requestId, userDN ) if not retVal[ 'OK' ]: return retVal request = retVal[ 'Value' ] chain = X509Chain( keyObj = request.getPKey() ) retVal = chain.loadChainFromString( delegatedPem ) if not retVal[ 'OK' ]: return retVal retVal = chain.isValidProxy( ignoreDefault = True ) if not retVal[ 'OK' ]: return retVal result = chain.isVOMS() if result[ 'OK' ] and result[ 'Value' ]: return S_ERROR( "Proxies with VOMS extensions are not allowed to be uploaded" ) retVal = request.checkChain( chain ) if not retVal[ 'OK' ]: return retVal if not retVal[ 'Value' ]: return S_ERROR( "Received chain does not match request: %s" % retVal[ 'Message' ] ) retVal = chain.getDIRACGroup() if not retVal[ 'OK' ]: return retVal userGroup = retVal[ 'Value' ] if not userGroup: userGroup = Registry.getDefaultUserGroup() retVal = Registry.getGroupsForDN( userDN ) if not retVal[ 'OK' ]: return retVal if not userGroup in retVal[ 'Value' ]: return S_ERROR( "%s group is not valid for %s" % ( userGroup, userDN ) ) retVal = self.storeProxy( userDN, userGroup, chain ) if not retVal[ 'OK' ]: return retVal retVal = self.deleteRequest( requestId ) if not retVal[ 'OK' ]: return retVal return S_OK()
def userName( self ): DN = self.__inTokenData( 'userDN' ) if not DN: return False result = Registry.getUsernameForDN( DN ) if not result[ 'OK' ]: return False return result[ 'Value' ]
def __getCredDict( self, DN, group ): """ Generate a credDict based on the credentials """ if not group or not DN: return {} users = Registry.getUsersInGroup( group ) if not users: gLogger.error( "Group %s does not have any user!" % group ) return {} result = Registry.getUsernameForDN( DN ) if not result[ 'OK' ]: return {} user = result[ 'Value' ] if user not in users: return {} return { 'DN' : DN, 'group' : group, 'username' : user }
def __checkStageAllowed( self, jobState): """Check if the job credentials allow to stage date """ result = jobState.getAttribute( "OwnerGroup" ) if not result[ 'OK' ]: self.jobLog.error( "Cannot retrieve OwnerGroup from DB: %s" % result[ 'Message' ] ) return S_ERROR( "Cannot get OwnerGroup" ) group = result[ 'Value' ] return Properties.STAGE_ALLOWED in Registry.getPropertiesForGroup( group )
def export_getVOByGroup(self, group): """ Returns the vo which the group belongs to. """ gLogger.info('getVOByGroup') return S_OK(Registry.getVOMSVOForGroup(group))
def export_getVOs(self): """ Returns the list of all VOs. """ gLogger.info('getVOs') return Registry.getVOs()
def __executeClient( self, host, method, *parms, **kwargs ): """ Execute RPC method on a given host """ hostName = Registry.getHostOption( host, 'Host', host) client = SystemAdministratorClient( hostName, **self.__kwargs ) result = getattr( client, method )( *parms, **kwargs ) result['Host'] = host return result
def __getOpsHelper( self, setup = False, vo = False ): if not setup: setup = self.srv_getClientSetup() if not vo: vo = Registry.getVOForGroup( self.getRemoteCredentials()[ 'group' ] ) cKey = ( vo, setup ) if cKey not in MatcherHandler.__opsCache: MatcherHandler.__opsCache[ cKey ] = Operations.Operations( vo = vo, setup = setup ) return MatcherHandler.__opsCache[ cKey ]
def mapVoToGroups( voname ): """ Returns all groups available for a given VO as a set. """ vo_dict = Registry.getGroupsForVO( voname ) if not vo_dict[ 'OK' ]: raise RuntimeError( 'Could not retrieve groups for vo %s.' % voname ) return set( vo_dict[ 'Value' ] )
def _checkCredentials(self, resourceDict, credDict): """ Check if we can get a job given the passed credentials """ if Properties.GENERIC_PILOT in credDict['properties']: # You can only match groups in the same VO if credDict['group'] == "hosts": # for the host case the VirtualOrganization parameter # is mandatory in resourceDict vo = resourceDict.get('VirtualOrganization', '') else: vo = Registry.getVOForGroup(credDict['group']) if 'OwnerGroup' not in resourceDict: result = Registry.getGroupsForVO(vo) if result['OK']: resourceDict['OwnerGroup'] = result['Value'] else: raise RuntimeError(result['Message']) else: # If it's a private pilot, the DN has to be the same if Properties.PILOT in credDict['properties']: self.log.notice("Setting the resource DN to the credentials DN") resourceDict['OwnerDN'] = credDict['DN'] # If it's a job sharing. The group has to be the same and just check that the DN (if any) # belongs to the same group elif Properties.JOB_SHARING in credDict['properties']: resourceDict['OwnerGroup'] = credDict['group'] self.log.notice("Setting the resource group to the credentials group") if 'OwnerDN' in resourceDict and resourceDict['OwnerDN'] != credDict['DN']: ownerDN = resourceDict['OwnerDN'] result = Registry.getGroupsForDN(resourceDict['OwnerDN']) if not result['OK']: raise RuntimeError(result['Message']) if credDict['group'] not in result['Value']: # DN is not in the same group! bad boy. self.log.notice("You cannot request jobs from DN %s. It does not belong to your group!" % ownerDN) resourceDict['OwnerDN'] = credDict['DN'] # Nothing special, group and DN have to be the same else: resourceDict['OwnerDN'] = credDict['DN'] resourceDict['OwnerGroup'] = credDict['group'] return resourceDict
def getPilotGroupsToUpload( self ): pilotUpload = Registry.getGroupOption( self.__piParams.diracGroup, "AutoUploadPilotProxy", self.__piParams.uploadPilot ) if not pilotUpload: return [] issuerCert = self.getIssuerCert() userDN = issuerCert.getSubjectDN()[ 'Value' ] result = Registry.getGroupsForDN( userDN ) if not result[ 'OK' ]: gLogger.error( "No groups defined for DN %s" % userDN ) return [] availableGroups = result[ 'Value' ] pilotGroups = [] for group in availableGroups: groupProps = Registry.getPropertiesForGroup( group ) if Properties.PILOT in groupProps or Properties.GENERIC_PILOT in groupProps: pilotGroups.append( group ) return pilotGroups
def __discoverSettings( self ): #Set the VO globalVO = CSGlobals.getVO() if globalVO: self.__vo = globalVO elif self.__uVO: self.__vo = self.__uVO else: self.__vo = Registry.getVOForGroup( self.__uGroup ) if not self.__vo: self.__vo = None