예제 #1
0
  public PutMetricDataResponseType putMetricData(PutMetricDataType request)
      throws CloudWatchException {
    PutMetricDataResponseType reply = request.getReply();
    final Context ctx = Contexts.lookup();

    try {
      LOG.trace("put metric data called");
      // IAM Action Check
      checkActionPermission(PolicySpec.CLOUDWATCH_PUTMETRICDATA, ctx);

      final OwnerFullName ownerFullName = ctx.getUserFullName();
      final List<MetricDatum> metricData = validateMetricData(request.getMetricData());
      final String namespace = validateNamespace(request.getNamespace(), true);
      final Boolean isUserAccountAdmin =
          Principals.isSameUser(
              Principals.systemUser(), Wrappers.unwrap(Context.class, Contexts.lookup()).getUser());
      LOG.trace("Namespace=" + namespace);
      LOG.trace("metricData=" + metricData);
      MetricType metricType = getMetricTypeFromNamespace(namespace);
      if (metricType == MetricType.System && !isUserAccountAdmin) {
        throw new InvalidParameterValueException(
            "The value AWS/ for parameter Namespace is invalid.");
      }
      MetricDataQueue.getInstance()
          .insertMetricData(ownerFullName.getAccountNumber(), namespace, metricData, metricType);
    } catch (Exception ex) {
      handleException(ex);
    }
    return reply;
  }
예제 #2
0
 public BaseMessage setUser(User user) {
   if (user == null) {
     this.setUser(Principals.nobodyUser());
   } else {
     this.userId = user.getName();
     this.effectiveUserId =
         user.isSystemAdmin() ? Principals.systemUser().getName() : user.getName();
   }
   return this;
 }
예제 #3
0
  /**
   * Just checks the basic S3 groups for membership of the userId. Caller must ensure that the
   * userId is a valid ID in the system. That is outside the scope of this method.
   *
   * @param userId
   * @param group
   * @return
   */
  public static boolean isUserMember(String userId, ObjectStorageProperties.S3_GROUP group) {
    if (group == null) {
      return false;
    }

    if (ObjectStorageProperties.S3_GROUP.ALL_USERS_GROUP.equals(group)) {
      return true;
    }

    if (ObjectStorageProperties.S3_GROUP.AUTHENTICATED_USERS_GROUP.equals(group)
        && !Strings.isNullOrEmpty(userId)
        && !userId.equals(Principals.nobodyUser().getUserId())) {
      return true;
    }

    boolean isSystemAdmin = false;
    try {
      isSystemAdmin =
          (Principals.systemUser().getUserId().equals(userId)
              || Accounts.lookupSystemAdmin().getUserId().equals(userId));
    } catch (AuthException e) {
      // Fall through
      LOG.debug(
          "Got auth exception trying to lookup system admin user for group membership check in ec2-bundle-read",
          e);
    }

    boolean isAWSExecReadUser = false;
    try {
      isAWSExecReadUser = Accounts.lookupAwsExecReadAdmin(false).getUserId().equals(userId);
    } catch (AuthException e) {
      // Fall through
      LOG.debug(
          "Got auth exception trying to lookup aws-exec-read admin user for group membership check in ec2-bundle-read",
          e);
    }

    if (ObjectStorageProperties.S3_GROUP.AWS_EXEC_READ.equals(group) && isAWSExecReadUser) {
      return true;
    }

    // System only (or euca/admin) in the ec2-bundle-read group
    if (ObjectStorageProperties.S3_GROUP.EC2_BUNDLE_READ.equals(group) && isSystemAdmin) {
      return true;
    }

    // System or euca/admin only in logging
    if (ObjectStorageProperties.S3_GROUP.LOGGING_GROUP.equals(group) && isSystemAdmin) {
      return true;
    }

    return false;
  }
예제 #4
0
 public <TYPE extends BaseMessage> TYPE regarding(BaseMessage msg, String subCorrelationId) {
   String corrId = null;
   if (msg == null) {
     this.correlationId = UUID.randomUUID().toString();
   } else {
     corrId = msg.correlationId;
   }
   if (subCorrelationId == null) {
     subCorrelationId = String.format("%f", Math.random()).substring(2);
   }
   this.userId = Principals.systemFullName().getUserName();
   this.effectiveUserId = Principals.systemFullName().getUserName();
   this.correlationId = corrId + "-" + subCorrelationId;
   return (TYPE) this;
 }
 public void update(final Cluster cluster, final List<ClusterAddressInfo> ccList) {
   Helper.loadStoredAddresses();
   for (final ClusterAddressInfo addrInfo : ccList) {
     try {
       final Address address = Helper.lookupOrCreate(cluster, addrInfo);
       if (address.isAssigned() && !addrInfo.hasMapping() && !address.isPending()) {
         if (Principals.nobodyFullName().equals(address.getOwner())) {
           Helper.markAsAllocated(cluster, addrInfo, address);
         }
         try {
           final VmInstance vm = VmInstances.lookupByPrivateIp(addrInfo.getInstanceIp());
           clearOrphan(addrInfo);
         } catch (final NoSuchElementException e) {
           try {
             final VmInstance vm = VmInstances.lookup(address.getInstanceId());
             clearOrphan(addrInfo);
           } catch (final NoSuchElementException ex) {
             InetAddress addr = null;
             try {
               addr = Inet4Address.getByName(addrInfo.getInstanceIp());
             } catch (final UnknownHostException e1) {
               LOG.debug(e1, e1);
             }
             if ((addr == null) || !addr.isLoopbackAddress()) {
               handleOrphan(cluster, addrInfo);
             }
           }
         }
       } else if (address.isAllocated()
           && Principals.nobodyFullName().equals(address.getOwner())
           && !address.isPending()) {
         Helper.markAsAllocated(cluster, addrInfo, address);
       }
     } catch (final Exception e) {
       LOG.debug(e, e);
     }
   }
 }
예제 #6
0
 public void init() { // Should only EVER be called externally after loading from the db
   this.atomicState = new AtomicMarkableReference<State>(State.unallocated, false);
   this.transition = this.QUIESCENT;
   this.getOwner(); // ensure to initialize
   if (this.instanceAddress == null || this.instanceId == null) {
     this.instanceAddress = UNASSIGNED_INSTANCEADDR;
     this.instanceUuid = UNASSIGNED_INSTANCEUUID;
     this.instanceId = UNASSIGNED_INSTANCEID;
   }
   if (Principals.nobodyFullName().equals(super.getOwner())) {
     this.atomicState.set(State.unallocated, true);
     this.instanceAddress = UNASSIGNED_INSTANCEADDR;
     this.instanceUuid = UNASSIGNED_INSTANCEUUID;
     this.instanceId = UNASSIGNED_INSTANCEID;
     Addresses.getInstance().registerDisabled(this);
     this.atomicState.set(State.unallocated, false);
   } else if (!this.instanceId.equals(UNASSIGNED_INSTANCEID)) {
     this.atomicState.set(State.assigned, true);
     Addresses.getInstance().register(this);
     this.atomicState.set(State.assigned, false);
   } else {
     this.atomicState.set(State.allocated, true);
     if (this.isSystemOwned()) {
       Addresses.getInstance().registerDisabled(this);
       this.setOwner(Principals.nobodyFullName());
       this.instanceAddress = UNASSIGNED_INSTANCEADDR;
       this.instanceUuid = UNASSIGNED_INSTANCEUUID;
       this.instanceId = UNASSIGNED_INSTANCEID;
       Address.removeAddress(this.getDisplayName());
       this.atomicState.set(State.unallocated, false);
     } else {
       Addresses.getInstance().register(this);
       this.atomicState.set(State.allocated, false);
     }
   }
   LOG.debug("Initialized address: " + this.toString());
 }
예제 #7
0
 private void fireUsageEvent(
     final OwnerFullName ownerFullName,
     final Supplier<EventActionInfo<AddressAction>> actionInfoSupplier) {
   if (!Principals.isFakeIdentityAccountNumber(ownerFullName.getAccountNumber())) {
     try {
       ListenerRegistry.getInstance()
           .fireEvent(
               AddressEvent.with(
                   getNaturalId(),
                   getDisplayName(),
                   ownerFullName,
                   Accounts.lookupAccountById(ownerFullName.getAccountNumber()).getName(),
                   actionInfoSupplier.get()));
     } catch (final Exception e) {
       LOG.error(e, e);
     }
   }
 }
예제 #8
0
  /*
   * Simply determines if the userId is a member of the groupId, very simplistic only for ALL_USERS and AUTHENTICATED_USERS, not arbitrary groups.
   * Arbitrary groups are not yet supported in Walrus bucket policies/IAM policies.
   */
  public static boolean isUserMember(String userId, String groupId) {
    if (groupId == null) {
      return false;
    }

    if (groupId.equals(WalrusProperties.ALL_USERS_GROUP)) {
      return true;
    }

    if (groupId.equals(WalrusProperties.AUTHENTICATED_USERS_GROUP)
        && userId != null
        && !"".equals(userId)
        && !userId.equals(Principals.nobodyUser().getUserId())) {
      return true;
    }

    return false;
  }
예제 #9
0
 @SuppressWarnings("unchecked")
 public <TYPE extends BaseMessage> TYPE markPrivileged() {
   this.effectiveUserId = Principals.systemUser().getName();
   return (TYPE) this;
 }
  /**
   * Evaluates the authorization for the operation requested, evaluates IAM, ACL, and bucket policy
   * (bucket policy not yet supported).
   *
   * @param request
   * @param bucketResourceEntity
   * @param objectResourceEntity
   * @param resourceAllocationSize the size for the quota check(s) if applicable
   * @return
   */
  public <T extends ObjectStorageRequestType> boolean operationAllowed(
      @Nonnull T request,
      @Nullable final S3AccessControlledEntity bucketResourceEntity,
      @Nullable final S3AccessControlledEntity objectResourceEntity,
      long resourceAllocationSize)
      throws IllegalArgumentException {
    /*
     * Process the operation's authz requirements based on the request type annotations
     */
    Ats requestAuthzProperties = Ats.from(request);
    ObjectStorageProperties.Permission[] requiredBucketACLPermissions = null;
    ObjectStorageProperties.Permission[] requiredObjectACLPermissions = null;
    Boolean allowOwnerOnly = null;
    RequiresACLPermission requiredACLs = requestAuthzProperties.get(RequiresACLPermission.class);
    if (requiredACLs != null) {
      requiredBucketACLPermissions = requiredACLs.bucket();
      requiredObjectACLPermissions = requiredACLs.object();
      allowOwnerOnly = requiredACLs.ownerOnly();
    } else {
      // No ACL annotation is ok, maybe a admin only op
    }

    String[] requiredActions = null;
    RequiresPermission perms = requestAuthzProperties.get(RequiresPermission.class);
    if (perms != null) {
      requiredActions = perms.value();
    }

    Boolean allowAdmin = (requestAuthzProperties.get(AdminOverrideAllowed.class) != null);
    Boolean allowOnlyAdmin =
        (requestAuthzProperties.get(AdminOverrideAllowed.class) != null)
            && requestAuthzProperties.get(AdminOverrideAllowed.class).adminOnly();

    // Must have at least one of: admin-only, owner-only, ACL, or IAM.
    if (requiredBucketACLPermissions == null
        && requiredObjectACLPermissions == null
        && requiredActions == null
        && !allowAdmin) {
      // Insufficient permission set on the message type.
      LOG.error(
          "Insufficient permission annotations on type: "
              + request.getClass().getName()
              + " cannot evaluate authorization");
      return false;
    }

    String resourceType = null;
    if (requestAuthzProperties.get(ResourceType.class) != null) {
      resourceType = requestAuthzProperties.get(ResourceType.class).value();
    }

    // Use these variables to isolate where all the AuthExceptions can happen on account/user
    // lookups
    User requestUser = null;
    String securityToken = null;
    Account requestAccount = null;
    AuthContextSupplier authContext = null;
    try {
      // Use context if available as it saves a DB lookup
      try {
        Context ctx = Contexts.lookup(request.getCorrelationId());
        requestUser = ctx.getUser();
        securityToken = ctx.getSecurityToken();
        requestAccount = requestUser.getAccount();
        authContext = ctx.getAuthContext();
      } catch (NoSuchContextException e) {
        requestUser = null;
        securityToken = null;
        requestAccount = null;
        authContext = null;
      }

      // This is not an expected path, but if no context found use the request credentials itself
      if (requestUser == null && !Strings.isNullOrEmpty(request.getEffectiveUserId())) {
        requestUser = Accounts.lookupUserById(request.getEffectiveUserId());
        requestAccount = requestUser.getAccount();
      }

      if (requestUser == null) {
        if (!Strings.isNullOrEmpty(request.getAccessKeyID())) {
          if (securityToken != null) {
            requestUser = SecurityTokenManager.lookupUser(request.getAccessKeyID(), securityToken);
          } else {
            requestUser = Accounts.lookupUserByAccessKeyId(request.getAccessKeyID());
          }
          requestAccount = requestUser.getAccount();
        } else {
          // Set to anonymous user since all else failed
          requestUser = Principals.nobodyUser();
          requestAccount = requestUser.getAccount();
        }
      }
    } catch (AuthException e) {
      LOG.error(
          "Failed to get user for request, cannot verify authorization: " + e.getMessage(), e);
      return false;
    }

    if (allowAdmin && requestUser.isSystemAdmin()) {
      // Admin override
      return true;
    }

    if (authContext == null) {
      authContext =
          Permissions.createAuthContextSupplier(
              requestUser, Collections.<String, String>emptyMap());
    }

    Account resourceOwnerAccount = null;
    if (resourceType == null) {
      LOG.error("No resource type found in request class annotations, cannot process.");
      return false;
    } else {
      try {
        // Ensure we have the proper resource entities present and get owner info
        if (PolicySpec.S3_RESOURCE_BUCKET.equals(resourceType)) {
          // Get the bucket owner.
          if (bucketResourceEntity == null) {
            LOG.error(
                "Could not check access for operation due to no bucket resource entity found");
            return false;
          } else {
            resourceOwnerAccount =
                Accounts.lookupAccountByCanonicalId(bucketResourceEntity.getOwnerCanonicalId());
          }
        } else if (PolicySpec.S3_RESOURCE_OBJECT.equals(resourceType)) {
          if (objectResourceEntity == null) {
            LOG.error(
                "Could not check access for operation due to no object resource entity found");
            return false;
          } else {
            resourceOwnerAccount =
                Accounts.lookupAccountByCanonicalId(objectResourceEntity.getOwnerCanonicalId());
          }
        }
      } catch (AuthException e) {
        LOG.error("Exception caught looking up resource owner. Disallowing operation.", e);
        return false;
      }
    }

    // Get the resourceId based on IAM resource type
    String resourceId = null;
    if (resourceId == null) {
      if (PolicySpec.S3_RESOURCE_BUCKET.equals(resourceType)) {
        resourceId = request.getBucket();
      } else if (PolicySpec.S3_RESOURCE_OBJECT.equals(resourceType)) {
        resourceId = request.getFullResource();
      }
    }

    if (allowAdmin
        && requestUser.isSystemUser()
        && iamPermissionsAllow(
            authContext, requiredActions, resourceType, resourceId, resourceAllocationSize)) {
      // Admin override
      return true;
    }

    if (requiredBucketACLPermissions == null && requiredObjectACLPermissions == null) {
      throw new IllegalArgumentException(
          "No requires-permission actions found in request class annotations, cannot process.");
    }

    /* ACL Checks: Is the user's account allowed? */
    Boolean aclAllow = false;
    if (requiredBucketACLPermissions != null && requiredBucketACLPermissions.length > 0) {
      // Check bucket ACLs

      if (bucketResourceEntity == null) {
        // There are bucket ACL requirements but no bucket entity to check. fail.
        // Don't bother with other checks, this is an invalid state
        LOG.error("Null bucket resource, cannot evaluate bucket ACL");
        return false;
      }

      // Evaluate the bucket ACL, any matching grant gives permission
      for (ObjectStorageProperties.Permission permission : requiredBucketACLPermissions) {
        aclAllow =
            aclAllow || bucketResourceEntity.can(permission, requestAccount.getCanonicalId());
      }
    }

    // Check object ACLs, if any
    if (requiredObjectACLPermissions != null && requiredObjectACLPermissions.length > 0) {
      if (objectResourceEntity == null) {
        // There are object ACL requirements but no object entity to check. fail.
        // Don't bother with other checks, this is an invalid state
        LOG.error("Null bucket resource, cannot evaluate bucket ACL");
        return false;
      }
      for (ObjectStorageProperties.Permission permission : requiredObjectACLPermissions) {
        aclAllow =
            aclAllow || objectResourceEntity.can(permission, requestAccount.getCanonicalId());
      }
    }

    /* Resource owner only? if so, override any previous acl decisions
     * It is not expected that owneronly is set as well as other ACL permissions,
     * Regular owner permissions (READ, WRITE, READ_ACP, WRITE_ACP) are handled by the regular acl checks.
     * OwnerOnly should be only used for operations not covered by the other Permissions (e.g. logging, or versioning)
     */
    aclAllow =
        (allowOwnerOnly
            ? resourceOwnerAccount.getAccountNumber().equals(requestAccount.getAccountNumber())
            : aclAllow);
    if (aclAllow && isUserAnonymous(requestUser)) {
      // Skip the IAM checks for anonymous access since they will always fail and aren't valid for
      // anonymous users.
      return true;
    } else {
      Boolean iamAllow =
          iamPermissionsAllow(
              authContext, requiredActions, resourceType, resourceId, resourceAllocationSize);
      // Must have both acl and iam allow (account & user)
      return aclAllow && iamAllow;
    }
  }
 /**
  * Does the current request have an authenticated user? Or is it anonymous?
  *
  * @return
  */
 protected static boolean isUserAnonymous(User usr) {
   return Principals.nobodyUser().equals(usr);
 }
 protected static Address lookupOrCreate(
     final Cluster cluster, final ClusterAddressInfo addrInfo) {
   Address addr = null;
   VmInstance vm = null;
   try {
     addr = Addresses.getInstance().lookupDisabled(addrInfo.getAddress());
     LOG.trace("Found address in the inactive set cache: " + addr);
   } catch (final NoSuchElementException e1) {
     try {
       addr = Addresses.getInstance().lookup(addrInfo.getAddress());
       LOG.trace("Found address in the active set cache: " + addr);
     } catch (final NoSuchElementException e) {
     }
   }
   if (addrInfo.hasMapping()) {
     vm =
         Helper.maybeFindVm(
             addr != null ? addr.getInstanceId() : null,
             addrInfo.getAddress(),
             addrInfo.getInstanceIp());
     if ((addr != null) && (vm != null)) {
       Helper.ensureAllocated(addr, vm);
       clearOrphan(addrInfo);
     } else if (addr != null && !addr.isPending() && vm != null && VmStateSet.DONE.apply(vm)) {
       handleOrphan(cluster, addrInfo);
     } else if ((addr != null && addr.isAssigned() && !addr.isPending()) && (vm == null)) {
       handleOrphan(cluster, addrInfo);
     } else if ((addr == null) && (vm != null)) {
       addr =
           new Address(
               Principals.systemFullName(),
               addrInfo.getAddress(),
               vm.getInstanceUuid(),
               vm.getInstanceId(),
               vm.getPrivateAddress());
       clearOrphan(addrInfo);
     } else if ((addr == null) && (vm == null)) {
       addr = new Address(addrInfo.getAddress(), cluster.getPartition());
       handleOrphan(cluster, addrInfo);
     }
   } else {
     if ((addr != null) && addr.isAssigned() && !addr.isPending()) {
       handleOrphan(cluster, addrInfo);
     } else if ((addr != null)
         && !addr.isAssigned()
         && !addr.isPending()
         && addr.isSystemOwned()) {
       try {
         addr.release();
       } catch (final Exception ex) {
         LOG.error(ex);
       }
     } else if ((addr != null) && Address.Transition.system.equals(addr.getTransition())) {
       handleOrphan(cluster, addrInfo);
     } else if (addr == null) {
       addr = new Address(addrInfo.getAddress(), cluster.getPartition());
       Helper.clearVmState(addrInfo);
     }
   }
   return addr;
 }
예제 #13
0
 public boolean isSystemOwned() {
   return Principals.systemFullName().equals((UserFullName) this.getOwner());
 }
예제 #14
0
 public Address(final String ipAddress) {
   super(Principals.nobodyFullName(), ipAddress);
 }