Revert "rgw ldap"

This commit is contained in:
Yehuda Sadeh 2016-03-12 20:07:04 -08:00
parent e4e9c2c021
commit 52ccf75cff
32 changed files with 55 additions and 1027 deletions

View File

@ -136,13 +136,6 @@ set(HAVE_LIBAIO ${AIO_FOUND})
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)

View File

@ -119,7 +119,6 @@ BuildRequires: libblkid-devel >= 2.17
BuildRequires: libudev-devel
BuildRequires: libtool
BuildRequires: make
BuildRequires: openldap-devel
BuildRequires: openssl-devel
BuildRequires: parted
BuildRequires: perl
@ -1109,7 +1108,6 @@ fi
%defattr(-,root,root,-)
%{_bindir}/radosgw
%{_bindir}/radosgw-admin
%{_bindir}/radosgw-token
%{_bindir}/radosgw-object-expirer
%{_mandir}/man8/radosgw.8*
%{_mandir}/man8/radosgw-admin.8*

View File

@ -1,37 +0,0 @@
# - 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
)

3
debian/control vendored
View File

@ -42,8 +42,7 @@ Build-Depends: autoconf,
libleveldb-dev,
libnss3-dev,
libsnappy-dev,
libldap2-dev,
libssl-dev,
libssl-dev,
liblttng-ust-dev,
libtool,
libudev-dev,

View File

@ -1,7 +1,6 @@
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

1
src/.gitignore vendored
View File

@ -74,7 +74,6 @@ Makefile
/rados
/radosgw
/radosgw-admin
/radosgw-token
/radosgw-object-expirer
/rbd
/rbd-mirror

View File

@ -1144,7 +1144,6 @@ if(${WITH_RADOSGW})
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
@ -1221,9 +1220,6 @@ if(${WITH_RADOSGW})
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)
@ -1261,8 +1257,7 @@ if(${WITH_RADOSGW})
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})
@ -1274,11 +1269,6 @@ if(${WITH_RADOSGW})
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

View File

@ -1237,21 +1237,6 @@ OPTION(rgw_keystone_revocation_interval, OPT_INT, 15 * 60) // seconds between t
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

View File

@ -44,7 +44,6 @@ librgw_la_SOURCES = \
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 \
@ -153,10 +152,6 @@ radosgw_admin_SOURCES = rgw/rgw_admin.cc rgw/rgw_orphan.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
@ -177,14 +172,12 @@ noinst_HEADERS += \
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 \

View File

@ -464,17 +464,6 @@ namespace rgw {
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);
@ -512,8 +501,6 @@ namespace rgw {
fe->join();
delete fe;
delete fec;
delete ldh;
rgw_log_usage_finalize();

View File

@ -1,87 +0,0 @@
// -*- 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 */

View File

@ -31,9 +31,6 @@
#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
@ -672,25 +669,9 @@ namespace rgw {
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,

View File

@ -1,4 +0,0 @@
// -*- mode:C++; tab-width:8; c-basic-offset:2; indent-tabs-mode:t -*-
// vim: ts=8 sw=2 smarttab
#include "rgw_ldap.h"

View File

@ -1,87 +0,0 @@
// -*- 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 */

View File

@ -12,8 +12,6 @@
#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;
@ -26,7 +24,6 @@ namespace rgw {
RGWFrontendConfig* fec;
RGWLibFrontend* fe;
OpsLogSocket* olog;
rgw::LDAPHelper* ldh;
RGWREST rest; // XXX needed for RGWProcessEnv
RGWRados* store;
@ -39,8 +36,6 @@ namespace rgw {
RGWLibFrontend* get_fe() { return fe; }
rgw::LDAPHelper* get_ldh() { return ldh; }
int init();
int init(vector<const char *>& args);
int stop();

View File

@ -27,9 +27,8 @@
#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

View File

@ -11,8 +11,6 @@
#include "rgw_op.h"
#include "rgw_rest.h"
#include "include/assert.h"
#include "common/WorkQueue.h"
#include "common/Throttle.h"

View File

@ -20,7 +20,6 @@
#include "rgw_rest_config.h"
#include "rgw_client_io.h"
#include "common/errno.h"
#include "include/assert.h"
#define dout_subsys ceph_subsys_rgw

View File

@ -19,7 +19,6 @@
#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

View File

@ -20,7 +20,6 @@
#include "rgw_client_io.h"
#include "common/errno.h"
#include "common/strtol.h"
#include "include/assert.h"
#define dout_subsys ceph_subsys_rgw

View File

@ -19,7 +19,6 @@
#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

View File

@ -6,8 +6,6 @@
#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

View File

@ -22,7 +22,6 @@
#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)

View File

@ -27,17 +27,10 @@
#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",
@ -1542,68 +1535,41 @@ int RGWPostObj_ObjStore_S3::get_policy()
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;
}
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 {
// 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;
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;
@ -2899,26 +2865,6 @@ int RGWHandler_REST_S3::init(RGWRados *store, struct req_state *s,
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
*/
@ -3029,9 +2975,8 @@ int RGW_Auth_S3::authorize(RGWRados *store, struct req_state *s)
{
/* 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;
}
@ -3646,7 +3591,7 @@ int RGW_Auth_S3::authorize_v2(RGWRados *store, struct req_state *s)
}
/* 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;
@ -3657,11 +3602,11 @@ int RGW_Auth_S3::authorize_v2(RGWRados *store, struct req_state *s)
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();
@ -3699,45 +3644,17 @@ int RGW_Auth_S3::authorize_v2(RGWRados *store, struct req_state *s)
}
}
if ((external_auth_result < 0) &&
(store->ctx()->_conf->rgw_s3_auth_use_ldap) &&
(! store->ctx()->_conf->rgw_ldap_uri.empty())) {
if (keystone_result < 0) {
if (!store->ctx()->_conf->rgw_s3_auth_use_rados) {
/* No other auth option possible. Terminate request. */
return keystone_result;
}
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;
/* 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 */
@ -3813,7 +3730,7 @@ int RGW_Auth_S3::authorize_v2(RGWRados *store, struct req_state *s)
}
}
} /* if external_auth_result < 0 */
} /* if keystone_result < 0 */
// populate the owner info
s->owner.set_id(s->user->user_id);

View File

@ -6,15 +6,12 @@
#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
@ -404,34 +401,15 @@ public:
};
class RGW_Auth_S3 {
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);
private:
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);
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;
}
static void init_impl(RGWRados* store);
};
class RGWHandler_Auth_S3 : public RGWHandler_REST {

View File

@ -8,7 +8,6 @@
#include "rgw_rest_user.h"
#include "include/str_list.h"
#include "include/assert.h"
#define dout_subsys ceph_subsys_rgw

View File

@ -1,135 +0,0 @@
// -*- 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;
}

View File

@ -1,169 +0,0 @@
// -*- 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 */

View File

@ -2221,22 +2221,6 @@ target_link_libraries(test_librgw_file_aw
${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
@ -2249,22 +2233,6 @@ if(${HAVE_LIBFUSE})
)
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

View File

@ -746,19 +746,6 @@ librgw_file_nfsns_LDADD = $(UNITTEST_LDADD) \
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

View File

@ -1,114 +0,0 @@
// -*- 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();
}

View File

@ -1,97 +0,0 @@
// -*- 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();
}