message(STATUS "${AIO_LIBS}")
endif(${WITH_AIO})
-option(WITH_OPENLDAP "OPENLDAP is here" ON)
-if(${WITH_OPENLDAP})
-find_package(OpenLdap REQUIRED)
-set(HAVE_OPENLDAP ${OPENLDAP_FOUND})
-message(STATUS "${OPENLDAP_LIBS}")
-endif(${WITH_OPENLDAP})
-
option(WITH_FUSE "Fuse is here" ON)
if(${WITH_FUSE})
find_package(fuse)
BuildRequires: libudev-devel
BuildRequires: libtool
BuildRequires: make
-BuildRequires: openldap-devel
BuildRequires: openssl-devel
BuildRequires: parted
BuildRequires: perl
%defattr(-,root,root,-)
%{_bindir}/radosgw
%{_bindir}/radosgw-admin
-%{_bindir}/radosgw-token
%{_bindir}/radosgw-object-expirer
%{_mandir}/man8/radosgw.8*
%{_mandir}/man8/radosgw-admin.8*
+++ /dev/null
-# - Find OpenLDAP C Libraries
-#
-# OPENLDAP_PREFIX - where to find ldap.h and libraries
-# OPENLDAP_FOUND - True if found.
-
-set(OPENLDAP_INCLUDE_DIR "${OPENLDAP_PREFIX}/include")
-set(OPENLDAP_LIB_DIR "${OPENLDAP_PREFIX}/lib")
-
-find_path(OPENLDAP_INCLUDE_DIR ldap.h NO_DEFAULT_PATH PATHS
- /usr/include
- /opt/local/include
- /usr/local/include
- )
-
-find_library(LIBLDAP NAMES ldap)
-find_library(LIBLBER NAMES lber)
-
-if (OPENLDAP_INCLUDE_DIR AND LIBLDAP AND LIBLBER)
- set(OPENLDAP_FOUND TRUE)
-else (OPENLDAP_INCLUDE_DIR AND LIBLDAP AND LIBLBER)
- set(OPENLDAP_FOUND FALSE)
-endif (OPENLDAP_INCLUDE_DIR AND LIBLDAP AND LIBLBER)
-
-if (OPENLDAP_FOUND)
- message(STATUS "Found ldap: ${OPENLDAP_INCLUDE_DIR}")
-else ()
- message(STATUS "Failed to find ldap.h")
- if (OPENLDAP_FIND_REQUIRED)
- message(FATAL_ERROR "Missing required ldap.h")
- endif ()
-endif ()
-
-set(OPENLDAP_LIBS ${LIBLDAP} ${LIBLBER})
-
-mark_as_advanced(
- OPENLDAP_INCLUDE_DIR OPENLDAP_LIB_DIR OPENLDAP_LIBRARIES
-)
libleveldb-dev,
libnss3-dev,
libsnappy-dev,
- libldap2-dev,
- libssl-dev,
+ libssl-dev,
liblttng-ust-dev,
libtool,
libudev-dev,
etc/bash_completion.d/radosgw-admin
usr/bin/radosgw
usr/bin/radosgw-admin
-usr/bin/radosgw-token
usr/bin/radosgw-object-expirer
usr/share/man/man8/radosgw-admin.8
usr/share/man/man8/radosgw.8
/rados
/radosgw
/radosgw-admin
-/radosgw-token
/radosgw-object-expirer
/rbd
/rbd-mirror
rgw/rgw_http_client.cc
rgw/rgw_json_enc.cc
rgw/rgw_keystone.cc
- rgw/rgw_ldap.cc
rgw/rgw_loadgen.cc
rgw/rgw_log.cc
rgw/rgw_metadata.cc
rgw/rgw_admin.cc
rgw/rgw_orphan.cc)
- set(radosgw_token_srcs
- rgw/rgw_token.cc)
-
set(radosgw_object_expirer_srcs
rgw/rgw_object_expirer.cc)
cls_rgw_client cls_lock_client cls_refcount_client
cls_log_client cls_statelog_client cls_timeindex_client
cls_version_client cls_replica_log_client cls_user_client
- curl expat global fcgi resolv ssl crypto ${BLKID_LIBRARIES} ${OPENLDAP_LIBS}
- ${ALLOC_LIBS})
+ curl expat global fcgi resolv ssl crypto ${BLKID_LIBRARIES})
install(TARGETS radosgw DESTINATION bin)
add_executable(radosgw-admin ${radosgw_admin_srcs})
install(TARGETS radosgw-admin DESTINATION bin)
- add_executable(radosgw-token ${radosgw_token_srcs})
- target_link_libraries(radosgw-token librados
- global ${ALLOC_LIBS})
- install(TARGETS radosgw-token DESTINATION bin)
-
add_executable(radosgw-object-expirer ${radosgw_object_expirer_srcs})
target_link_libraries(radosgw-object-expirer rgw_a librados
cls_rgw_client cls_lock_client cls_refcount_client
OPTION(rgw_keystone_verify_ssl, OPT_BOOL, true) // should we try to verify keystone's ssl
OPTION(rgw_s3_auth_use_rados, OPT_BOOL, true) // should we try to use the internal credentials for s3?
OPTION(rgw_s3_auth_use_keystone, OPT_BOOL, false) // should we try to use keystone for s3?
-
-/* OpenLDAP-style LDAP parameter strings */
-/* rgw_ldap_uri space-separated list of LDAP servers in URI format */
-OPTION(rgw_ldap_uri, OPT_STR, "ldaps://<ldap.your.domain>")
-/* rgw_ldap_binddn LDAP entry RGW will bind with (user match) */
-OPTION(rgw_ldap_binddn, OPT_STR, "uid=admin,cn=users,dc=example,dc=com")
-/* rgw_ldap_searchdn LDAP search base (basedn) */
-OPTION(rgw_ldap_searchdn, OPT_STR, "cn=users,cn=accounts,dc=example,dc=com")
-/* rgw_ldap_memberattr LDAP attribute containing RGW user names */
-OPTION(rgw_ldap_memberattr, OPT_STR, "uid")
-/* rgw_ldap_secret file containing credentials for rgw_ldap_binddn */
-OPTION(rgw_ldap_secret, OPT_STR, "/etc/openldap/secret")
-/* rgw_s3_auth_use_ldap use LDAP for RGW auth? */
-OPTION(rgw_s3_auth_use_ldap, OPT_BOOL, false)
-
OPTION(rgw_admin_entry, OPT_STR, "admin") // entry point for which a url is considered an admin request
OPTION(rgw_enforce_swift_acls, OPT_BOOL, true)
OPTION(rgw_swift_token_expiration, OPT_INT, 24 * 3600) // time in seconds for swift token expiration
rgw/rgw_http_client.cc \
rgw/rgw_json_enc.cc \
rgw/rgw_keystone.cc \
- rgw/rgw_ldap.cc \
rgw/rgw_loadgen.cc \
rgw/rgw_log.cc \
rgw/rgw_metadata.cc \
radosgw_admin_LDADD = $(LIBRGW) $(LIBRGW_DEPS) $(CEPH_GLOBAL)
bin_PROGRAMS += radosgw-admin
-radosgw_token_SOURCES = rgw/rgw_token.cc
-radosgw_token_LDADD = $(LIBRGW) $(LIBRGW_DEPS) $(CEPH_GLOBAL)
-bin_PROGRAMS += radosgw-token
-
radosgw_object_expirer_SOURCES = rgw/rgw_object_expirer.cc
radosgw_object_expirer_LDADD = $(LIBRGW) $(LIBRGW_DEPS) $(CEPH_GLOBAL)
bin_PROGRAMS += radosgw-object-expirer
rgw/rgw_acl.h \
rgw/rgw_acl_s3.h \
rgw/rgw_acl_swift.h \
- rgw/rgw_b64.h \
rgw/rgw_client_io.h \
rgw/rgw_coroutine.h \
rgw/rgw_cr_rados.h \
rgw/rgw_cr_rest.h \
rgw/rgw_fcgi.h \
rgw/rgw_xml.h \
- rgw/rgw_token.h \
rgw/rgw_basic_types.h \
rgw/rgw_cache.h \
rgw/rgw_common.h \
if (r)
return -EIO;
- const string& ldap_uri = store->ctx()->_conf->rgw_ldap_uri;
- const string& ldap_binddn = store->ctx()->_conf->rgw_ldap_binddn;
- const string& ldap_searchdn = store->ctx()->_conf->rgw_ldap_searchdn;
- const string& ldap_memberattr =
- store->ctx()->_conf->rgw_ldap_memberattr;
-
- ldh = new rgw::LDAPHelper(ldap_uri, ldap_binddn, ldap_searchdn,
- ldap_memberattr);
- ldh->init();
- ldh->bind();
-
rgw_user_init(store);
rgw_bucket_init(store->meta_mgr);
rgw_log_usage_init(g_ceph_context, store);
fe->join();
delete fe;
- delete fec;
- delete ldh;
rgw_log_usage_finalize();
+++ /dev/null
-// -*- mode:C++; tab-width:8; c-basic-offset:2; indent-tabs-mode:t -*-
-// vim: ts=8 sw=2 smarttab
-
-#ifndef RGW_B64_H
-#define RGW_B64_H
-
-#include <boost/utility/string_ref.hpp>
-#include <boost/archive/iterators/base64_from_binary.hpp>
-#include <boost/archive/iterators/binary_from_base64.hpp>
-#include <boost/archive/iterators/insert_linebreaks.hpp>
-#include <boost/archive/iterators/transform_width.hpp>
-#include <boost/archive/iterators/remove_whitespace.hpp>
-#include <limits>
-
-namespace rgw {
-
- /*
- * A header-only Base64 encoder built on boost::archive. The
- * formula is based on a class poposed for inclusion in boost in
- * 2011 by Denis Shevchenko (abandoned), updated slightly
- * (e.g., uses boost::string_ref).
- *
- * Also, wrap_width added as template argument, based on
- * feedback from Marcus.
- */
-
- template<int wrap_width = std::numeric_limits<int>::max()>
- inline std::string to_base64(boost::string_ref sref)
- {
- using namespace boost::archive::iterators;
- std::string ostr;
-
- // output must be =padded modulo 3
- auto psize = sref.size();
- while ((psize % 3) != 0) {
- ++psize;
- }
-
- /* RFC 2045 requires linebreaks to be present in the output
- * sequence every at-most 76 characters (MIME-compliance),
- * but we could likely omit it. */
- typedef
- insert_linebreaks<
- base64_from_binary<
- transform_width<
- boost::string_ref::const_iterator
- ,6,8>
- >
- ,wrap_width
- > b64_iter;
-
- std::string outstr(b64_iter(sref.data()),
- b64_iter(sref.data() + sref.size()));
-
- // pad ostr with '=' to a length that is a multiple of 3
- for (size_t ix = 0; ix < (psize-sref.size()); ++ix)
- outstr.push_back('=');
-
- return std::move(outstr);
- }
-
- inline std::string from_base64(boost::string_ref sref)
- {
- using namespace boost::archive::iterators;
-
- /* MIME-compliant input will have line-breaks, so we have to
- * filter WS */
- typedef
- transform_width<
- binary_from_base64<
- remove_whitespace<
- boost::string_ref::const_iterator>>
- ,8,6
- > b64_iter;
-
- while (sref.back() == '=')
- sref.remove_suffix(1);
-
- std::string outstr(b64_iter(sref.data()),
- b64_iter(sref.data() + sref.size()));
-
- return std::move(outstr);
- }
-
-} /* namespace */
-
-#endif /* RGW_B64_H */
#include "rgw_common.h"
#include "rgw_user.h"
#include "rgw_lib.h"
-#include "rgw_ldap.h"
-#include "rgw_token.h"
-
/* XXX
* ASSERT_H somehow not defined after all the above (which bring
return -EINVAL;
if (user.suspended)
return -ERR_USER_SUSPENDED;
- } else {
- /* try external authenticators (ldap for now) */
- rgw::LDAPHelper* ldh = rgwlib.get_ldh(); /* !nullptr */
- RGWToken token{from_base64(key.id)};
- if (ldh->auth(token.id, token.key) == 0) {
- /* try to store user if it doesn't already exist */
- if (rgw_get_user_info_by_uid(store, token.id, user) < 0) {
- int ret = rgw_store_user_info(store, user, NULL, NULL, 0,
- true);
- if (ret < 0) {
- lsubdout(get_context(), rgw, 10)
- << "NOTICE: failed to store new user's info: ret=" << ret
- << dendl;
- }
- }
- } /* auth success */
}
return ret;
- } /* authorize */
+ }
/* find or create an RGWFileHandle */
LookupFHResult lookup_fh(RGWFileHandle* parent, const char *name,
+++ /dev/null
-// -*- mode:C++; tab-width:8; c-basic-offset:2; indent-tabs-mode:t -*-
-// vim: ts=8 sw=2 smarttab
-
-#include "rgw_ldap.h"
+++ /dev/null
-// -*- mode:C++; tab-width:8; c-basic-offset:2; indent-tabs-mode:t -*-
-// vim: ts=8 sw=2 smarttab
-
-#ifndef RGW_LDAP_H
-#define RGW_LDAP_H
-
-#define LDAP_DEPRECATED 1
-#include "ldap.h"
-
-#include <stdint.h>
-#include <tuple>
-#include <vector>
-#include <string>
-#include <iostream>
-
-namespace rgw {
-
- class LDAPHelper
- {
- std::string uri;
- std::string binddn;
- std::string searchdn;
- std::string memberattr;
- LDAP *ldap;
-
- public:
- LDAPHelper(std::string _uri, std::string _binddn, std::string _searchdn,
- std::string _memberattr)
- : uri(std::move(_uri)), binddn(std::move(_binddn)), searchdn(_searchdn),
- memberattr(_memberattr), ldap(nullptr) {
- // nothing
- }
-
- int init() {
- int ret;
- ret = ldap_initialize(&ldap, uri.c_str());
- return (ret == LDAP_SUCCESS) ? ret : -EINVAL;
- }
-
- int bind() {
- int ret;
- ret = ldap_simple_bind_s(ldap, nullptr, nullptr);
- return (ret == LDAP_SUCCESS) ? ret : -EINVAL;
- }
-
- int simple_bind(const char *dn, const std::string& pwd) {
- LDAP* tldap;
- int ret = ldap_initialize(&tldap, uri.c_str());
- ret = ldap_simple_bind_s(tldap, dn, pwd.c_str());
- if (ret == LDAP_SUCCESS) {
- ldap_unbind(tldap);
- }
- return ret; // OpenLDAP client error space
- }
-
- int auth(const std::string uid, const std::string pwd) {
- int ret;
- std::string filter;
- filter = "(";
- filter += memberattr;
- filter += "=";
- filter += uid;
- filter += ")";
- char *attrs[] = { const_cast<char*>(memberattr.c_str()), nullptr };
- LDAPMessage *answer, *entry;
- ret = ldap_search_s(ldap, searchdn.c_str(), LDAP_SCOPE_SUBTREE,
- filter.c_str(), attrs, 0, &answer);
- if (ret == LDAP_SUCCESS) {
- entry = ldap_first_entry(ldap, answer);
- char *dn = ldap_get_dn(ldap, entry);
- ret = simple_bind(dn, pwd);
- ldap_memfree(dn);
- ldap_msgfree(answer);
- }
- return (ret == LDAP_SUCCESS) ? ret : -EACCES;
- }
-
- ~LDAPHelper() {
- if (ldap)
- ldap_unbind(ldap);
- }
-
- };
-
-} /* namespace rgw */
-
-#endif /* RGW_LDAP_H */
#include "rgw_frontend.h"
#include "rgw_process.h"
#include "rgw_rest_s3.h" // RGW_Auth_S3
-#include "rgw_ldap.h"
-#include "include/assert.h"
class OpsLogSocket;
RGWFrontendConfig* fec;
RGWLibFrontend* fe;
OpsLogSocket* olog;
- rgw::LDAPHelper* ldh;
RGWREST rest; // XXX needed for RGWProcessEnv
RGWRados* store;
RGWLibFrontend* get_fe() { return fe; }
- rgw::LDAPHelper* get_ldh() { return ldh; }
-
int init();
int init(vector<const char *>& args);
int stop();
#include "rgw_cors_s3.h"
#include "rgw_rest_conn.h"
#include "rgw_rest_s3.h"
-#include "rgw_client_io.h"
-#include "include/assert.h"
+#include "rgw_client_io.h"
#define dout_subsys ceph_subsys_rgw
#include "rgw_op.h"
#include "rgw_rest.h"
-#include "include/assert.h"
-
#include "common/WorkQueue.h"
#include "common/Throttle.h"
#include "rgw_rest_config.h"
#include "rgw_client_io.h"
#include "common/errno.h"
-#include "include/assert.h"
#define dout_subsys ceph_subsys_rgw
#include "rgw_rest_log.h"
#include "rgw_client_io.h"
#include "common/errno.h"
-#include "include/assert.h"
#define LOG_CLASS_LIST_MAX_ENTRIES (1000)
#define dout_subsys ceph_subsys_rgw
#include "rgw_client_io.h"
#include "common/errno.h"
#include "common/strtol.h"
-#include "include/assert.h"
#define dout_subsys ceph_subsys_rgw
#include "rgw_rest_opstate.h"
#include "rgw_client_io.h"
#include "common/errno.h"
-#include "include/assert.h"
#define OPSTATE_LIST_MAX_ENTRIES 1000
#define dout_subsys ceph_subsys_rgw
#include "rgw_rest_s3.h"
#include "rgw_rest_config.h"
-#include "include/assert.h"
-
#define dout_subsys ceph_subsys_rgw
// reject 'period push' if we would have to fetch too many intermediate periods
#include "rgw_rest_replica_log.h"
#include "rgw_client_io.h"
#include "common/errno.h"
-#include "include/assert.h"
#define dout_subsys ceph_subsys_rgw
#define REPLICA_INPUT_MAX_LEN (512*1024)
#include <typeinfo> // for 'typeid'
-#include "rgw_ldap.h"
-#include "rgw_token.h"
-#include "include/assert.h"
-
#define dout_subsys ceph_subsys_rgw
-using namespace rgw;
using namespace ceph::crypto;
-using std::get;
-
void list_all_buckets_start(struct req_state *s)
{
s->formatter->open_array_section_in_ns("ListAllMyBucketsResult",
op_ret = rgw_get_user_info_by_access_key(store, s3_access_key, user_info);
if (op_ret < 0) {
- // try external authenticators
- if (store->ctx()->_conf->rgw_s3_auth_use_keystone &&
- store->ctx()->_conf->rgw_keystone_url.empty())
- {
- // keystone
- int external_auth_result = -EINVAL;
- dout(20) << "s3 keystone: trying keystone auth" << dendl;
-
- RGW_Auth_S3_Keystone_ValidateToken keystone_validator(store->ctx());
- external_auth_result =
- keystone_validator.validate_s3token(s3_access_key,
- string(encoded_policy.c_str(),
- encoded_policy.length()),
- received_signature_str);
-
- if (external_auth_result < 0) {
- ldout(s->cct, 0) << "User lookup failed!" << dendl;
- err_msg = "Bad access key / signature";
- return -EACCES;
- }
+ // Try keystone authentication as well
+ int keystone_result = -EINVAL;
+ if (!store->ctx()->_conf->rgw_s3_auth_use_keystone ||
+ store->ctx()->_conf->rgw_keystone_url.empty()) {
+ return -EACCES;
+ }
+ dout(20) << "s3 keystone: trying keystone auth" << dendl;
- string project_id = keystone_validator.response.get_project_id();
- rgw_user uid(project_id);
-
- user_info.user_id = project_id;
- user_info.display_name = keystone_validator.response.get_project_name();
-
- /* try to store user if it not already exists */
- if (rgw_get_user_info_by_uid(store, uid, user_info) < 0) {
- int ret = rgw_store_user_info(store, user_info, NULL, NULL, 0, true);
- if (ret < 0) {
- ldout(store->ctx(), 10)
- << "NOTICE: failed to store new user's info: ret="
- << ret << dendl;
- }
- s->perm_mask = RGW_PERM_FULL_CONTROL;
- }
- } else if (store->ctx()->_conf->rgw_s3_auth_use_ldap &&
- store->ctx()->_conf->rgw_ldap_uri.empty()) {
- RGWToken token{from_base64(s3_access_key)};
- rgw::LDAPHelper *ldh = RGW_Auth_S3::get_ldap_ctx(store);
- if (ldh->auth(token.id, token.key) != 0)
- return -EACCES;
-
- /* ok, succeeded, try to create shadow */
- user_info.user_id = token.id;
- user_info.display_name = token.id; // cn?
-
- /* try to store user if it not already exists */
- if (rgw_get_user_info_by_uid(store, user_info.user_id,
- user_info) < 0) {
- int ret = rgw_store_user_info(store, user_info, NULL, NULL, 0, true);
- if (ret < 0) {
- ldout(store->ctx(), 10)
- << "NOTICE: failed to store new user's info: ret=" << ret
- << dendl;
- }
- s->perm_mask = RGW_PERM_FULL_CONTROL;
- }
- } else {
+ RGW_Auth_S3_Keystone_ValidateToken keystone_validator(store->ctx());
+ keystone_result =
+ keystone_validator.validate_s3token(s3_access_key,
+ string(encoded_policy.c_str(),
+ encoded_policy.length()),
+ received_signature_str);
+
+ if (keystone_result < 0) {
+ ldout(s->cct, 0) << "User lookup failed!" << dendl;
+ err_msg = "Bad access key / signature";
return -EACCES;
}
+
+ string project_id = keystone_validator.response.get_project_id();
+ user_info.user_id = project_id;
+ user_info.display_name = keystone_validator.response.get_project_name();
+
+ rgw_user uid(project_id);
+ /* try to store user if it not already exists */
+ if (rgw_get_user_info_by_uid(store, uid, user_info) < 0) {
+ int ret = rgw_store_user_info(store, user_info, NULL, NULL, 0, true);
+ if (ret < 0) {
+ dout(10) << "NOTICE: failed to store new user's info: ret="
+ << ret << dendl;
+ }
+ s->perm_mask = RGW_PERM_FULL_CONTROL;
+ }
} else {
map<string, RGWAccessKey> access_keys = user_info.access_keys;
return RGWHandler_REST::init(store, s, cio);
}
-/* RGW_Auth_S3 static members */
-std::mutex RGW_Auth_S3::mtx;
-rgw::LDAPHelper* RGW_Auth_S3::ldh;
-
-/* static */
-void RGW_Auth_S3::init_impl(RGWRados* store)
-{
- const string& ldap_uri = store->ctx()->_conf->rgw_ldap_uri;
- const string& ldap_binddn = store->ctx()->_conf->rgw_ldap_binddn;
- const string& ldap_searchdn = store->ctx()->_conf->rgw_ldap_searchdn;
- const string& ldap_memberattr =
- store->ctx()->_conf->rgw_ldap_memberattr;
-
- ldh = new rgw::LDAPHelper(ldap_uri, ldap_binddn, ldap_searchdn,
- ldap_memberattr);
-
- ldh->init();
- ldh->bind();
-}
-
/*
* Try to validate S3 auth against keystone s3token interface
*/
{
/* neither keystone and rados enabled; warn and exit! */
- if (!store->ctx()->_conf->rgw_s3_auth_use_rados &&
- !store->ctx()->_conf->rgw_s3_auth_use_keystone &&
- !store->ctx()->_conf->rgw_s3_auth_use_ldap) {
+ if (!store->ctx()->_conf->rgw_s3_auth_use_rados
+ && !store->ctx()->_conf->rgw_s3_auth_use_keystone) {
dout(0) << "WARNING: no authorization backend enabled! Users will never authenticate." << dendl;
return -EPERM;
}
}
/* try keystone auth first */
- int external_auth_result = -ERR_INVALID_ACCESS_KEY;;
+ int keystone_result = -ERR_INVALID_ACCESS_KEY;;
if (store->ctx()->_conf->rgw_s3_auth_use_keystone
&& !store->ctx()->_conf->rgw_keystone_url.empty()) {
dout(20) << "s3 keystone: trying keystone auth" << dendl;
if (!rgw_create_s3_canonical_header(s->info,
&s->header_time, token, qsr)) {
dout(10) << "failed to create auth header\n" << token << dendl;
- external_auth_result = -EPERM;
+ keystone_result = -EPERM;
} else {
- external_auth_result = keystone_validator.validate_s3token(auth_id, token,
+ keystone_result = keystone_validator.validate_s3token(auth_id, token,
auth_sign);
- if (external_auth_result == 0) {
+ if (keystone_result == 0) {
// Check for time skew first
time_t req_sec = s->header_time.sec();
}
}
- if ((external_auth_result < 0) &&
- (store->ctx()->_conf->rgw_s3_auth_use_ldap) &&
- (! store->ctx()->_conf->rgw_ldap_uri.empty())) {
-
- RGW_Auth_S3::init(store);
-
- RGWToken token{from_base64(auth_id)};
- if (ldh->auth(token.id, token.key) != 0)
- external_auth_result = -EACCES;
- else {
- /* ok, succeeded */
- external_auth_result = 0;
- /* create local account, if none exists */
- s->user->user_id = token.id;
- s->user->display_name = token.id; // cn?
- if (rgw_get_user_info_by_uid(store, s->user->user_id,
- *(s->user)) < 0) {
- int ret = rgw_store_user_info(store, *(s->user), NULL, NULL, 0, true);
- if (ret < 0) {
- dout(10) << "NOTICE: failed to store new user's info: ret=" << ret
- << dendl;
- }
- s->perm_mask = RGW_PERM_FULL_CONTROL;
- }
- } /* success */
- } /* ldap */
-
- /* keystone failed (or not enabled); check if we want to use rados backend */
- if (!store->ctx()->_conf->rgw_s3_auth_use_rados
- && external_auth_result < 0)
- return external_auth_result;
+ if (keystone_result < 0) {
+ if (!store->ctx()->_conf->rgw_s3_auth_use_rados) {
+ /* No other auth option possible. Terminate request. */
+ return keystone_result;
+ }
- /* now try rados backend, but only if keystone did not succeed */
- if (external_auth_result < 0) {
/* get the user info */
if (rgw_get_user_info_by_access_key(store, auth_id, *(s->user)) < 0) {
dout(5) << "error reading user info, uid=" << auth_id
<< " can't authenticate" << dendl;
- return external_auth_result;
+ return keystone_result;
}
/* now verify signature */
}
}
- } /* if external_auth_result < 0 */
+ } /* if keystone_result < 0 */
// populate the owner info
s->owner.set_id(s->user->user_id);
#define CEPH_RGW_REST_S3_H
#define TIME_BUF_SIZE 128
-#include <mutex>
-
#include "rgw_op.h"
#include "rgw_http_errors.h"
#include "rgw_acl_s3.h"
#include "rgw_policy_s3.h"
#include "rgw_keystone.h"
#include "rgw_rest_conn.h"
-#include "rgw_ldap.h"
#define RGW_AUTH_GRACE_MINS 15
};
class RGW_Auth_S3 {
+public:
+ static int authorize(RGWRados *store, struct req_state *s);
+ static int authorize_aws4_auth_complete(RGWRados *store, struct req_state *s);
private:
- static std::mutex mtx;
- static rgw::LDAPHelper* ldh;
-
static int authorize_v2(RGWRados *store, struct req_state *s);
static int authorize_v4(RGWRados *store, struct req_state *s);
static int authorize_v4_complete(RGWRados *store, struct req_state *s,
- const string& request_payload,
- bool unsigned_payload);
-public:
- static int authorize(RGWRados *store, struct req_state *s);
- static int authorize_aws4_auth_complete(RGWRados *store, struct req_state *s);
-
- static inline void init(RGWRados* store) {
- if (! ldh) {
- std::lock_guard<std::mutex> lck(mtx);
- if (! ldh) {
- init_impl(store);
- }
- }
- }
-
- static inline rgw::LDAPHelper* get_ldap_ctx(RGWRados* store) {
- init(store);
- return ldh;
- }
+ const string& request_payload, bool unsigned_payload);
- static void init_impl(RGWRados* store);
};
class RGWHandler_Auth_S3 : public RGWHandler_REST {
#include "rgw_rest_user.h"
#include "include/str_list.h"
-#include "include/assert.h"
#define dout_subsys ceph_subsys_rgw
+++ /dev/null
-// -*- mode:C++; tab-width:8; c-basic-offset:2; indent-tabs-mode:t -*-
-// vim: ts=8 sw=2 smarttab
-/*
- * Ceph - scalable distributed file system
- *
- * Copyright (C) 2016 Red Hat, Inc.
- *
- * This is free software; you can redistribute it and/or
- * modify it under the terms of the GNU Lesser General Public
- * License version 2.1, as published by the Free Software
- * Foundation. See file COPYING.
- *
- */
-
-#include <errno.h>
-#include <iostream>
-#include <sstream>
-#include <string>
-
-#include "common/config.h"
-#include "common/ceph_argparse.h"
-#include "common/debug.h"
-#include "global/global_init.h"
-#include "include/assert.h"
-#include "include/str_list.h"
-
-#include "rgw_token.h"
-#include "rgw_b64.h"
-
-#define dout_subsys ceph_subsys_rgw
-
-namespace {
-
- using namespace rgw;
- using std::get;
- using std::string;
-
- RGWToken::token_type type{RGWToken::TOKEN_NONE};
- string access_key{""};
- string secret_key{""};
-
- Formatter* formatter{nullptr};
-
- bool verbose {false};
- bool do_encode {false};
- bool do_decode {false};
-
-}
-
-void usage()
-{
- cout << "usage: radosgw-token --encode --ttype=<token type> [options...]" << std::endl;
- cout << "\t(maybe exporting RGW_ACCESS_KEY_ID and RGW_SECRET_ACCESS_KEY)"
- << std::endl;
- cout << "\t <token type> := ad | ldap" << std::endl;
- cout << "\n";
- generic_client_usage();
-}
-
-int main(int argc, char **argv)
-{
- std::string val;
- vector<const char*> args;
- argv_to_vec(argc, (const char **)argv, args);
- env_to_vec(args);
-
- global_init(NULL, args, CEPH_ENTITY_TYPE_CLIENT, CODE_ENVIRONMENT_UTILITY, 0);
- common_init_finish(g_ceph_context);
-
- char *v{nullptr};
- v = getenv("RGW_ACCESS_KEY_ID");
- if (v) {
- access_key = v;
- }
-
- v = getenv("RGW_SECRET_ACCESS_KEY");
- if (v) {
- secret_key = v;
- }
-
- for (auto arg_iter = args.begin(); arg_iter != args.end();) {
- if (ceph_argparse_witharg(args, arg_iter, &val, "--access",
- (char*) nullptr)) {
- access_key = val;
- } else if (ceph_argparse_witharg(args, arg_iter, &val, "--secret",
- (char*) nullptr)) {
- secret_key = val;
- } else if (ceph_argparse_witharg(args, arg_iter, &val, "--ttype",
- (char*) nullptr)) {
- for (const auto& ttype : {"ad", "ldap"}) {
- if (boost::iequals(val, ttype)) {
- type = RGWToken::to_type(val);
- break;
- }
- }
- } else if (ceph_argparse_flag(args, arg_iter, "--encode",
- (char*) nullptr)) {
- do_encode = true;
- } else if (ceph_argparse_flag(args, arg_iter, "--decode",
- (char*) nullptr)) {
- do_decode = true;
- } else if (ceph_argparse_flag(args, arg_iter, "--verbose",
- (char*) nullptr)) {
- verbose = true;
- } else {
- ++arg_iter;
- }
- }
-
- if ((! do_encode) ||
- (type == RGWToken::TOKEN_NONE)) {
- usage();
- return -EINVAL;
- }
-
- formatter = new JSONFormatter(true /* pretty */);
-
- RGWToken token(type, access_key, secret_key);
- if (do_encode) {
- token.encode_json(formatter);
- std::ostringstream os;
- formatter->flush(os);
- string token_str = os.str();
- if (verbose) {
- std::cout << "expanded token: " << token_str << std::endl;
- if (do_decode) {
- RGWToken token2(token_str);
- std::cout << "decoded expanded token: " << token2 << std::endl;
- }
- }
- std::cout << to_base64(token_str) << std::endl;
- }
-
- return 0;
-}
+++ /dev/null
-// -*- mode:C++; tab-width:8; c-basic-offset:2; indent-tabs-mode:t -*-
-// vim: ts=8 sw=2 smarttab
-/*
- * Ceph - scalable distributed file system
- *
- * Copyright (C) 2016 Red Hat, Inc
- *
- * This is free software; you can redistribute it and/or
- * modify it under the terms of the GNU Lesser General Public
- * License version 2.1, as published by the Free Software
- * Foundation. See file COPYING.
- *
- */
-
-#ifndef RGW_TOKEN_H
-#define RGW_TOKEN_H
-
-#include <stdint.h>
-#include <boost/algorithm/string.hpp>
-#include <sstream>
-
-#include "common/ceph_json.h"
-#include "common/Formatter.h"
-#include "rgw/rgw_b64.h"
-
-namespace rgw {
-
- using std::string;
-
- class RGWToken {
- public:
- static constexpr auto type_name = "RGW_TOKEN";
-
- enum token_type : uint32_t {
- TOKEN_NONE,
- TOKEN_AD,
- TOKEN_KEYSTONE,
- TOKEN_LDAP,
- };
-
- static enum token_type to_type(const string& s) {
- if (boost::iequals(s, "ad"))
- return TOKEN_AD;
- if (boost::iequals(s, "ldap"))
- return TOKEN_LDAP;
- if (boost::iequals(s, "keystone"))
- return TOKEN_KEYSTONE;
- return TOKEN_NONE;
- }
-
- static const char* from_type(enum token_type type) {
- switch (type) {
- case TOKEN_AD:
- return "ad";
- break;
- case TOKEN_LDAP:
- return "ldap";
- break;
- case TOKEN_KEYSTONE:
- return "keystone";
- break;
- default:
- return "none";
- };
- return "none";
- }
-
- token_type type;
- string id;
- string key;
-
- virtual uint32_t version() const { return 1; };
-
- bool valid() {
- return ((type != TOKEN_NONE) &&
- (! id.empty()) &&
- (! key.empty()));
- }
-
- RGWToken()
- : type(TOKEN_NONE) {};
-
- RGWToken(enum token_type _type, const std::string& _id,
- const std::string& _key)
- : type(_type), id(_id), key(_key) {};
-
- RGWToken(const string& json) {
- JSONParser p;
- p.parse(json.c_str(), json.length());
- JSONDecoder::decode_json(RGWToken::type_name, *this, &p);
- }
-
- void encode(bufferlist& bl) const {
- uint32_t ver = version();
- string typestr{from_type(type)};
- ENCODE_START(1, 1, bl);
- ::encode(type_name, bl);
- ::encode(ver, bl);
- ::encode(typestr, bl);
- ::encode(id, bl);
- ::encode(key, bl);
- ENCODE_FINISH(bl);
- }
-
- void decode(bufferlist::iterator& bl) {
- string name;
- string typestr;
- uint32_t version;
- DECODE_START(1, bl);
- ::decode(name, bl);
- ::decode(version, bl);
- ::decode(typestr, bl);
- type = to_type(typestr.c_str());
- ::decode(id, bl);
- ::decode(key, bl);
- DECODE_FINISH(bl);
- }
-
- void dump(Formatter* f) const {
- ::encode_json("version", uint32_t(version()), f);
- ::encode_json("type", from_type(type), f);
- ::encode_json("id", id, f);
- ::encode_json("key", key, f);
- }
-
- void encode_json(Formatter* f) {
- RGWToken& token = *this;
- f->open_object_section(type_name);
- ::encode_json(type_name, token, f);
- f->close_section();
- }
-
- void decode_json(JSONObj* obj) {
- uint32_t version;
- string type_name;
- string typestr;
- JSONDecoder::decode_json("version", version, obj);
- JSONDecoder::decode_json("type", typestr, obj);
- type = to_type(typestr.c_str());
- JSONDecoder::decode_json("id", id, obj);
- JSONDecoder::decode_json("key", key, obj);
- }
-
- std::string encode_json_base64(Formatter* f) {
- encode_json(f);
- std::ostringstream os;
- f->flush(os);
- return std::move(to_base64(std::move(os.str())));
- }
-
- friend inline ostream& operator<<(ostream& os, const RGWToken& token);
-
- virtual ~RGWToken() {};
- };
- WRITE_CLASS_ENCODER(RGWToken)
-
- inline ostream& operator<<(ostream& os, const RGWToken& token)
- {
- os << "<<RGWToken"
- << " type=" << RGWToken::from_type(token.type)
- << " id=" << token.id
- << " key=" << token.key
- << ">>";
- return os;
- }
-
-} /* namespace rgw */
-
-#endif /* RGW_TOKEN_H */
${CMAKE_DL_LIBS}
)
-add_executable(test_rgw_token
- test_rgw_token.cc
- $<TARGET_OBJECTS:heap_profiler_objs>
- )
-set_target_properties(test_rgw_token PROPERTIES COMPILE_FLAGS
- ${UNITTEST_CXX_FLAGS})
-target_link_libraries(test_rgw_token
- rgw
- os
- global
- ${UNITTEST_LIBS}
- ${EXTRALIBS}
- ${ALLOC_LIBS}
- ${CMAKE_DL_LIBS}
- )
-
if(${HAVE_LIBFUSE})
add_executable(test_cfuse_cache_invalidate
test_cfuse_cache_invalidate.cc
)
endif(${HAVE_LIBFUSE})
-# librgw_file_gp (just the rgw_file get-put bucket ops)
-add_executable(test_rgw_ldap
- ../rgw/rgw_ldap.cc
- test_rgw_ldap.cc
- $<TARGET_OBJECTS:heap_profiler_objs>
- )
-set_target_properties(test_rgw_ldap PROPERTIES COMPILE_FLAGS
- ${UNITTEST_CXX_FLAGS})
-target_link_libraries(test_rgw_ldap
- librados
- ${OPENLDAP_LIBS}
- ${Boost_LIBRARIES}
- ${ALLOC_LIBS}
- ${UNITTEST_LIBS}
- )
-
if(${WITH_CEPHFS})
add_executable(test_c_headers
test_c_headers.c
librgw.la librados.la $(PTHREAD_LIBS) $(CEPH_GLOBAL) $(EXTRALIBS)
bin_DEBUGPROGRAMS += librgw_file_nfsns
-test_rgw_token_SOURCES = test/test_rgw_token.cc
-test_rgw_token_CXXFLAGS = $(UNITTEST_CXXFLAGS)
-test_rgw_token_LDADD = $(UNITTEST_LDADD) \
- librgw.la $(PTHREAD_LIBS) $(LIBOS) $(CEPH_GLOBAL) $(EXTRALIBS)
-bin_DEBUGPROGRAMS += test_rgw_token
-
-test_rgw_ldap_SOURCES = ../rgw/rgw_ldap.cc test/test_rgw_ldap.cc
-test_rgw_ldap_CXXFLAGS = $(UNITTEST_CXXFLAGS)
-test_rgw_ldap_LDADD = $(UNITTEST_LDADD) \
- librados.la $(PTHREAD_LIBS) $(LIBOS) $(CEPH_GLOBAL) ${OPENLDAP_LIBS}
- $(EXTRALIBS)
-bin_DEBUGPROGRAMS += test_rgw_token
-
endif # WITH_RADOSGW
+++ /dev/null
-// -*- mode:C++; tab-width:8; c-basic-offset:2; indent-tabs-mode:t -*-
-// vim: ts=8 sw=2 smarttab
-/*
- * Ceph - scalable distributed file system
- *
- * Copyright (C) 2015 New Dream Network
- *
- * This is free software; you can redistribute it and/or
- * modify it under the terms of the GNU Lesser General Public
- * License version 2.1, as published by the Free Software
- * Foundation. See file COPYING.
- *
- */
-
-#include <stdint.h>
-#include <tuple>
-#include <iostream>
-#include <vector>
-#include <map>
-#include <random>
-
-#include "rgw/rgw_ldap.h"
-#include "rgw/rgw_token.h"
-
-#include "gtest/gtest.h"
-#include "common/ceph_argparse.h"
-#include "common/debug.h"
-#include "global/global_init.h"
-
-#define dout_subsys ceph_subsys_rgw
-
-namespace {
-
- struct {
- int argc;
- char **argv;
- } saved_args;
-
- bool do_hexdump = false;
-
- string access_key("ewogICAgIlJHV19UT0tFTiI6IHsKICAgICAgICAidmVyc2lvbiI6IDEsCiAgICAgICAgInR5cGUiOiAibGRhcCIsCiAgICAgICAgImlkIjogImFkbWluIiwKICAgICAgICAia2V5IjogImxpbnV4Ym94IgogICAgfQp9Cg=="); // {admin,linuxbox}
- string other_key("ewogICAgIlJHV19UT0tFTiI6IHsKICAgICAgICAidmVyc2lvbiI6IDEsCiAgICAgICAgInR5cGUiOiAibGRhcCIsCiAgICAgICAgImlkIjogImFkbWluIiwKICAgICAgICAia2V5IjogImJhZHBhc3MiCiAgICB9Cn0K"); // {admin,badpass}
-
- string ldap_uri = "ldaps://f23-kdc.rgw.com";
- string ldap_binddn = "uid=admin,cn=users,cn=accounts,dc=rgw,dc=com";
- string ldap_searchdn = "cn=users,cn=accounts,dc=rgw,dc=com";
- string ldap_memberattr = "uid";
-
- rgw::LDAPHelper ldh(ldap_uri, ldap_binddn, ldap_searchdn, ldap_memberattr);
-
-} /* namespace */
-
-TEST(RGW_LDAP, INIT) {
- int ret = ldh.init();
- ASSERT_EQ(ret, 0);
-}
-
-TEST(RGW_LDAP, BIND) {
- int ret = ldh.bind();
- ASSERT_EQ(ret, 0);
-}
-
-TEST(RGW_LDAP, AUTH) {
- using std::get;
- using namespace rgw;
- int ret = 0;
- {
- RGWToken token{from_base64(access_key)};
- ret = ldh.auth(token.id, token.key);
- ASSERT_EQ(ret, 0);
- }
- {
- RGWToken token{from_base64(other_key)};
- ret = ldh.auth(token.id, token.key);
- ASSERT_NE(ret, 0);
- }
-}
-
-TEST(RGW_LDAP, SHUTDOWN) {
- // nothing
-}
-
-int main(int argc, char *argv[])
-{
- string val;
- vector<const char*> args;
-
- argv_to_vec(argc, const_cast<const char**>(argv), args);
- env_to_vec(args);
-
- for (auto arg_iter = args.begin(); arg_iter != args.end();) {
- if (ceph_argparse_witharg(args, arg_iter, &val, "--access",
- (char*) nullptr)) {
- access_key = val;
- } else if (ceph_argparse_flag(args, arg_iter, "--hexdump",
- (char*) nullptr)) {
- do_hexdump = true;
- } else {
- ++arg_iter;
- }
- }
-
- /* dont accidentally run as anonymous */
- if (access_key == "") {
- std::cout << argv[0] << " no AWS credentials, exiting" << std::endl;
- return EPERM;
- }
-
- saved_args.argc = argc;
- saved_args.argv = argv;
-
- ::testing::InitGoogleTest(&argc, argv);
- return RUN_ALL_TESTS();
-}
+++ /dev/null
-// -*- mode:C++; tab-width:8; c-basic-offset:2; indent-tabs-mode:t -*-
-// vim: ts=8 sw=2 smarttab
-/*
- * Ceph - scalable distributed file system
- *
- * Copyright (C) 2016 Red Hat, Inc.
- *
- * This is free software; you can redistribute it and/or
- * modify it under the terms of the GNU Lesser General Public
- * License version 2.1, as published by the Free Software
- * Foundation. See file COPYING.
- *
- */
-
-#include <errno.h>
-#include <iostream>
-#include <sstream>
-#include <string>
-
-#include "common/config.h"
-#include "common/ceph_argparse.h"
-#include "common/debug.h"
-#include "global/global_init.h"
-#include "include/assert.h"
-#include "gtest/gtest.h"
-#include "rgw/rgw_token.h"
-#include "rgw/rgw_b64.h"
-
-#define dout_subsys ceph_subsys_rgw
-
-namespace {
-
- using namespace rgw;
- using std::get;
- using std::string;
-
- string access_key{"Smonny"};
- string secret_key{"Turjan of Miir"};
-
- std::vector<RGWToken> tokens;
-
- std::string enc_ad{"ewogICAgIlJHV19UT0tFTiI6IHsKICAgICAgICAidmVyc2lvbiI6IDEsCiAgICAgICAgInR5cGUiOiAiYWQiLAogICAgICAgICJpZCI6ICJTbW9ubnkiLAogICAgICAgICJrZXkiOiAiVHVyamFuIG9mIE1paXIiCiAgICB9Cn0K"};
-
- std::string enc_ldap{"ewogICAgIlJHV19UT0tFTiI6IHsKICAgICAgICAidmVyc2lvbiI6IDEsCiAgICAgICAgInR5cGUiOiAibGRhcCIsCiAgICAgICAgImlkIjogIlNtb25ueSIsCiAgICAgICAgImtleSI6ICJUdXJqYW4gb2YgTWlpciIKICAgIH0KfQo="};
-
- Formatter* formatter{nullptr};
- bool verbose {false};
-}
-
-TEST(TOKEN, INIT) {
- formatter = new JSONFormatter(true /* pretty */);
- ASSERT_NE(formatter, nullptr);
-}
-
-TEST(TOKEN, ENCODE) {
- // encode the two supported types
- RGWToken token_ad(RGWToken::TOKEN_AD, access_key, secret_key);
- ASSERT_EQ(token_ad.encode_json_base64(formatter), enc_ad);
- tokens.push_back(token_ad); // provies copiable
-
- RGWToken token_ldap(RGWToken::TOKEN_LDAP, access_key, secret_key);
- ASSERT_EQ(token_ldap.encode_json_base64(formatter), enc_ldap);
- tokens.push_back(token_ldap);
-}
-
-TEST(TOKEN, DECODE) {
- for (const auto& enc_tok : {enc_ad, enc_ldap}) {
- RGWToken token{from_base64(enc_tok)}; // decode ctor
- ASSERT_EQ(token.id, access_key);
- ASSERT_EQ(token.key, secret_key);
- }
-}
-
-TEST(TOKEN, SHUTDOWN) {
- delete formatter;
-}
-
-int main(int argc, char *argv[])
-{
- string val;
- vector<const char*> args;
-
- argv_to_vec(argc, const_cast<const char**>(argv), args);
- env_to_vec(args);
-
- for (auto arg_iter = args.begin(); arg_iter != args.end();) {
- if (ceph_argparse_flag(args, arg_iter, "--verbose",
- (char*) nullptr)) {
- verbose = true;
- } else {
- ++arg_iter;
- }
- }
-
- ::testing::InitGoogleTest(&argc, argv);
- return RUN_ALL_TESTS();
-}