int RGWPutObj::verify_permission()
{
  if (! copy_source.empty()) {

    RGWAccessControlPolicy cs_acl(s->cct);
    boost::optional<Policy> policy;
    map<string, bufferlist> cs_attrs;
    rgw_bucket cs_bucket(copy_source_bucket_info.bucket);
    rgw_obj_key cs_object(copy_source_object_name, copy_source_version_id);

    rgw_obj obj(cs_bucket, cs_object);
    store->set_atomic(s->obj_ctx, obj);
    store->set_prefetch_data(s->obj_ctx, obj);

    /* check source object permissions */
    if (read_obj_policy(store, s, copy_source_bucket_info, cs_attrs, &cs_acl,
			policy, cs_bucket, cs_object) < 0) {
      return -EACCES;
    }

    /* admin request overrides permission checks */
    if (! s->auth.identity->is_admin_of(cs_acl.get_owner().get_id())) {
      if (policy) {
	auto e = policy->eval(s->env, *s->auth.identity,
			      cs_object.instance.empty() ?
			      rgw::IAM::s3GetObject :
			      rgw::IAM::s3GetObjectVersion,
			      rgw::IAM::ARN(obj));
	if (e == Effect::Deny) {
	  return -EACCES; 
	} else if (e == Effect::Pass &&
		   !cs_acl.verify_permission(*s->auth.identity, s->perm_mask,
						RGW_PERM_READ)) {
	  return -EACCES;
	}
      } else if (!cs_acl.verify_permission(*s->auth.identity, s->perm_mask,
					   RGW_PERM_READ)) {
	return -EACCES;
      }
    }
  }

  auto op_ret = get_params();
  if (op_ret < 0) {
    ldout(s->cct, 20) << "get_params() returned ret=" << op_ret << dendl;
    return op_ret;
  }

  if (s->iam_policy) {
    rgw_add_grant_to_iam_environment(s->env, s);

    rgw_add_to_iam_environment(s->env, "s3:x-amz-acl", s->canned_acl);

    if (obj_tags != nullptr && obj_tags->count() > 0){
      auto tags = obj_tags->get_tags();
      for (const auto& kv: tags){
        rgw_add_to_iam_environment(s->env, "s3:RequestObjectTag/"+kv.first, kv.second);
      }
    }

    constexpr auto encrypt_attr = "x-amz-server-side-encryption";
    constexpr auto s3_encrypt_attr = "s3:x-amz-server-side-encryption";
    auto enc_header = s->info.x_meta_map.find(encrypt_attr);
    if (enc_header != s->info.x_meta_map.end()){
      rgw_add_to_iam_environment(s->env, s3_encrypt_attr, enc_header->second);
    }

    constexpr auto kms_attr = "x-amz-server-side-encryption-aws-kms-key-id";
    constexpr auto s3_kms_attr = "s3:x-amz-server-side-encryption-aws-kms-key-id";
    auto kms_header = s->info.x_meta_map.find(kms_attr);
    if (kms_header != s->info.x_meta_map.end()){
      rgw_add_to_iam_environment(s->env, s3_kms_attr, kms_header->second);
    }

    auto e = s->iam_policy->eval(s->env, *s->auth.identity,
				 rgw::IAM::s3PutObject,
				 rgw_obj(s->bucket, s->object));
    if (e == Effect::Allow) {
      return 0;
    } else if (e == Effect::Deny) {
      return -EACCES;
    }
  }

  if (!verify_bucket_permission_no_policy(s, RGW_PERM_WRITE)) {
    return -EACCES;
  }

  return 0;
}
int RGWPutObj::verify_permission()
{
  if (! copy_source.empty()) {

    RGWAccessControlPolicy cs_acl(s->cct);
    boost::optional<Policy> policy;
    map<string, bufferlist> cs_attrs;
    rgw_bucket cs_bucket(copy_source_bucket_info.bucket);
    rgw_obj_key cs_object(copy_source_object_name, copy_source_version_id);

    rgw_obj obj(cs_bucket, cs_object);
    store->set_atomic(s->obj_ctx, obj);
    store->set_prefetch_data(s->obj_ctx, obj);

     
    if (read_obj_policy(store, s, copy_source_bucket_info, cs_attrs, &cs_acl,
			policy, cs_bucket, cs_object) < 0) {
      return -EACCES;
    }

     
    if (! s->auth.identity->is_admin_of(cs_acl.get_owner().get_id())) {
      if (policy) {
	auto e = policy->eval(s->env, *s->auth.identity,
			      cs_object.instance.empty() ?
			      rgw::IAM::s3GetObject :
			      rgw::IAM::s3GetObjectVersion,
			      rgw::IAM::ARN(obj));
	if (e == Effect::Deny) {
	  return -EACCES; 
	} else if (e == Effect::Pass &&
		   !cs_acl.verify_permission(*s->auth.identity, s->perm_mask,
						RGW_PERM_READ)) {
	  return -EACCES;
	}
      } else if (!cs_acl.verify_permission(*s->auth.identity, s->perm_mask,
					   RGW_PERM_READ)) {
	return -EACCES;
      }
    }
  }

  auto op_ret = get_params();
  if (op_ret < 0) {
    ldout(s->cct, 20) << "get_params() returned ret=" << op_ret << dendl;
    return op_ret;
  }

  if (s->iam_policy) {
    rgw_add_grant_to_iam_environment(s->env, s);

    rgw_add_to_iam_environment(s->env, "s3:x-amz-acl", s->canned_acl);

    if (obj_tags != nullptr && obj_tags->count() > 0){
      auto tags = obj_tags->get_tags();
      for (const auto& kv: tags){
        rgw_add_to_iam_environment(s->env, "s3:RequestObjectTag/"+kv.first, kv.second);
      }
    }

    constexpr auto encrypt_attr = "x-amz-server-side-encryption";
    constexpr auto s3_encrypt_attr = "s3:x-amz-server-side-encryption";
    auto enc_header = s->info.x_meta_map.find(encrypt_attr);
    if (enc_header != s->info.x_meta_map.end()){
      rgw_add_to_iam_environment(s->env, s3_encrypt_attr, enc_header->second);
    }

    constexpr auto kms_attr = "x-amz-server-side-encryption-aws-kms-key-id";
    constexpr auto s3_kms_attr = "s3:x-amz-server-side-encryption-aws-kms-key-id";
    auto kms_header = s->info.x_meta_map.find(kms_attr);
    if (kms_header != s->info.x_meta_map.end()){
      rgw_add_to_iam_environment(s->env, s3_kms_attr, kms_header->second);
    }

    auto e = s->iam_policy->eval(s->env, *s->auth.identity,
				 rgw::IAM::s3PutObject,
				 rgw_obj(s->bucket, s->object));
    if (e == Effect::Allow) {
      return 0;
    } else if (e == Effect::Deny) {
      return -EACCES;
    }
  }

  if (!verify_bucket_permission_no_policy(s, RGW_PERM_WRITE)) {
    return -EACCES;
  }

  return 0;
}