def lookup_user(self, user, rhost, vhost_in, conn_name, conn_id): """ Lookup function called from C. Determine if a user on host accessing vhost through AMQP Open is allowed according to the policy access rules. If allowed then return the policy vhost settings name. If stats.can_connect returns true then it has registered and counted the connection. @param[in] user connection authId @param[in] rhost connection remote host numeric IP address as string @param[in] vhost_in vhost user is accessing @param[in] conn_name connection name used for tracking reports @param[in] conn_id internal connection id @return settings user-group name if allowed; "" if not allowed """ try: # choose rule set based on incoming vhost or default vhost # or potential vhost found by pattern matching vhost = vhost_in if self.use_hostname_patterns: agent = self._manager.get_agent() vhost = agent.qd.qd_dispatch_policy_host_pattern_lookup( agent.dispatch, vhost) if vhost not in self.rulesetdb: if self.default_vhost_enabled(): vhost = self._default_vhost else: self._manager.log_info( "DENY AMQP Open for user '%s', rhost '%s', vhost '%s': " "No policy defined for vhost" % (user, rhost, vhost_in)) return "" if vhost != vhost_in: self._manager.log_debug( "AMQP Open for user '%s', rhost '%s', vhost '%s': " "proceeds using vhost '%s' ruleset" % (user, rhost, vhost_in, vhost)) ruleset = self.rulesetdb[vhost] # look up the stats if vhost not in self.statsdb: msg = ("DENY AMQP Open for user '%s', rhost '%s', vhost '%s': " "INTERNAL: Policy is defined but stats are missing" % (user, rhost, vhost)) raise PolicyError(msg) stats = self.statsdb[vhost] # Get settings for user in a user group or in default if user in ruleset[PolicyKeys.RULESET_U2G_MAP]: usergroup = ruleset[PolicyKeys.RULESET_U2G_MAP][user] elif "*" in ruleset[PolicyKeys.RULESET_U2G_MAP]: usergroup = ruleset[PolicyKeys.RULESET_U2G_MAP]["*"] else: if ruleset[PolicyKeys.KW_CONNECTION_ALLOW_DEFAULT]: usergroup = PolicyKeys.KW_DEFAULT_SETTINGS else: self._manager.log_info( "DENY AMQP Open for user '%s', rhost '%s', vhost '%s': " "User is not in a user group and unknown users are denied" % (user, rhost, vhost)) stats.count_other_denial() return "" groupsettings = ruleset[PolicyKeys.KW_GROUPS][usergroup] # User in usergroup allowed to connect from rhost? allowed = False if PolicyKeys.KW_REMOTE_HOSTS in groupsettings: # Users are restricted to connecting from a rhost # defined by the group's remoteHost list cglist = groupsettings[PolicyKeys.KW_REMOTE_HOSTS] uhs = HostStruct(rhost) for cohost in cglist: if cohost.match_bin(uhs): allowed = True break if not allowed: self._manager.log_info( "DENY AMQP Open for user '%s', rhost '%s', vhost '%s': " "User is not allowed to connect from this network host" % (user, rhost, vhost)) stats.count_other_denial() return "" # This user passes administrative approval. # Now check live connection counts diags = [] if not stats.can_connect(conn_name, user, rhost, diags): for diag in diags: self._manager.log_info( "DENY AMQP Open for user '%s', rhost '%s', vhost '%s': " "%s" % (user, rhost, vhost, diag)) return "" # Record facts about this connection to use during teardown facts = ConnectionFacts(user, rhost, vhost, conn_name) self._connections[conn_id] = facts # Return success return usergroup except Exception, e: self._manager.log_info( "DENY AMQP Open lookup_user failed for user '%s', rhost '%s', vhost '%s': " "Internal error: %s" % (user, rhost, vhost, e)) # return failure return ""