rgw: added rgw-policy-check

rgw-policy-check - a program to do syntax checking on bucket policy.
This program just reads the policy into memory, so it is not
checking anything except syntax.

Signed-off-by: Marcus Watts <mwatts@redhat.com>

rgw: Fix return value of `rgw-policy-check`

Signed-off-by: Adam C. Emerson <aemerson@redhat.com>

rgw: Use ceph initialization in `rgw-policy-check`

Specifically so we can pull in the options from `ceph.conf` and similar.

Signed-off-by: Adam C. Emerson <aemerson@redhat.com>
This commit is contained in:
Marcus Watts
2022-11-30 18:22:30 -05:00
committed by Adam C. Emerson
parent 0b0fd44f42
commit 28864311d3
7 changed files with 171 additions and 0 deletions

View File

@@ -2129,7 +2129,9 @@ fi
%{_bindir}/rgw-gap-list
%{_bindir}/rgw-gap-list-comparator
%{_bindir}/rgw-orphan-list
%{_bindir}/rgw-policy-check
%{_mandir}/man8/radosgw.8*
%{_mandir}/man8/rgw-policy-check.8*
%dir %{_localstatedir}/lib/ceph/radosgw
%{_unitdir}/ceph-radosgw@.service
%{_unitdir}/ceph-radosgw.target

View File

@@ -37,6 +37,7 @@ usr/share/man/man8/crushdiff.8
usr/share/man/man8/mount.ceph.8
usr/share/man/man8/rados.8
usr/share/man/man8/radosgw-admin.8
usr/share/man/man8/rgw-policy-check.8
usr/share/man/man8/rbd.8
usr/share/man/man8/rbdmap.8
usr/share/man/man8/rbd-replay*.8

View File

@@ -59,6 +59,7 @@ if(WITH_RADOSGW)
radosgw.rst
radosgw-admin.rst
rgw-orphan-list.rst
rgw-policy-check.rst
ceph-diff-sorted.rst)
endif()

View File

@@ -0,0 +1,55 @@
:orphan:
===================================================
rgw-policy-check -- verify syntax of bucket policy
===================================================
.. program:: rgw-policy-check
Synopsis
========
| **rgw-policy-check**
-t *tenant* [ *filename* ... ]
Description
===========
This program reads one or more files containing bucket policy
and determines if it is syntactically correct.
It does not check to see if the policy makes sense;
it only checks to see if the file would be accepted
by the policy parsing logic inside
:program:`radsogw`.
More than one filename may be specified. If no files are
given, the program will read from stdin.
On success, the program will say nothing. On failure,
the program will emit a error message indicating the
problem. The program will terminate with non-zero exit
status if one or more policies could not be read or parsed.
Options
=======
.. option: -t *tenant*
Specify *tenant* as the tenant. This is required by the
policy parsing logic and is used to construct the internal
state representation of the policy.
Availability
============
**rgw-policy-check** is part of Ceph, a massively scalable, open-source,
distributed storage system. Please refer to the Ceph documentation at
http://ceph.com/docs for more information.
See also
========
:doc:`radosgw <radosgw>`\(8)
.. _Bucket Policies: ../../radosgw/bucketpolicy.rst

View File

@@ -47,3 +47,4 @@
man/8/rgw-orphan-list
man/8/ceph-immutable-object-cache
man/8/ceph-diff-sorted
man/8/rgw-policy-check

View File

@@ -459,6 +459,12 @@ target_link_libraries(radosgw-object-expirer ${rgw_libs} librados
${CURL_LIBRARIES} ${EXPAT_LIBRARIES})
install(TARGETS radosgw-object-expirer DESTINATION bin)
set(radosgw_polparser_srcs
rgw_polparser.cc)
add_executable(rgw-policy-check ${radosgw_polparser_srcs})
target_link_libraries(rgw-policy-check ${rgw_libs})
install(TARGETS rgw-policy-check DESTINATION bin)
set(librgw_srcs
librgw.cc)
add_library(rgw SHARED ${librgw_srcs})

105
src/rgw/rgw_polparser.cc Normal file
View File

@@ -0,0 +1,105 @@
// -*- mode:C++; tab-width:8; c-basic-offset:2; indent-tabs-mode:t -*-
// vim: ts=8 sw=2 smarttab
#include <cstdint>
#include <cstdlib>
#include <exception>
#include <fstream>
#include <iostream>
#include <string>
#include <string_view>
#include "include/buffer.h"
#include "common/ceph_argparse.h"
#include "common/common_init.h"
#include "global/global_init.h"
#include "rgw/rgw_iam_policy.h"
// Returns true on success
bool parse(CephContext* cct, const std::string& tenant,
const std::string& fname, std::istream& in) noexcept
{
bufferlist bl;
bl.append(in);
try {
auto p = rgw::IAM::Policy(
cct, tenant, bl,
cct->_conf.get_val<bool>("rgw_policy_reject_invalid_principals"));
} catch (const rgw::IAM::PolicyParseException& e) {
std::cerr << fname << ": " << e.what() << std::endl;
return false;
} catch (const std::exception& e) {
std::cerr << fname << ": caught exception: " << e.what() << std::endl;;
return false;
}
return true;
}
void helpful_exit(std::string_view cmdname)
{
std::cerr << cmdname << "-h for usage" << std::endl;
exit(1);
}
void usage(std::string_view cmdname)
{
std::cout << "usage: " << cmdname << " -t <tenant> [filename]"
<< std::endl;
}
int main(int argc, const char** argv)
{
std::string_view cmdname = argv[0];
std::string tenant;
auto args = argv_to_vec(argc, argv);
if (ceph_argparse_need_usage(args)) {
usage(cmdname);
exit(0);
}
auto cct = global_init(nullptr, args, CEPH_ENTITY_TYPE_CLIENT,
CODE_ENVIRONMENT_UTILITY,
CINIT_FLAG_NO_DAEMON_ACTIONS |
CINIT_FLAG_NO_MON_CONFIG);
common_init_finish(cct.get());
std::string val;
for (std::vector<const char*>::iterator i = args.begin(); i != args.end(); ) {
if (ceph_argparse_double_dash(args, i)) {
break;
} else if (ceph_argparse_witharg(args, i, &val, "--tenant", "-t",
(char*)nullptr)) {
tenant = std::move(val);
} else {
++i;
}
}
if (tenant.empty()) {
std::cerr << cmdname << ": must specify tenant name" << std::endl;
helpful_exit(cmdname);
}
bool success = true;
if (args.empty()) {
success = parse(cct.get(), tenant, "(stdin)", std::cin);
} else {
for (const auto& file : args) {
std::ifstream in;
in.open(file, std::ifstream::in);
if (!in.is_open()) {
std::cerr << "Can't read " << file << std::endl;
success = false;
}
if (!parse(cct.get(), tenant, file, in)) {
success = false;
}
}
}
return success ? 0 : 1;
}