Merge PR #23550 into master

* refs/pull/23550/head:
	auth: Kerberos authentication
This commit is contained in:
Sage Weil 2018-12-05 13:42:17 -06:00
commit 59d0844c12
39 changed files with 2273 additions and 17 deletions

View File

@ -232,6 +232,12 @@ if(WITH_OPENLDAP)
set(HAVE_OPENLDAP ${OPENLDAP_FOUND})
endif()
option(WITH_GSSAPI "GSSAPI/KRB5 is here" ON)
if(WITH_GSSAPI)
find_package(GSSApi REQUIRED)
set(HAVE_GSSAPI ${GSSApi_FOUND})
endif()
option(WITH_FUSE "Fuse is here" ON)
if(WITH_FUSE)
find_package(fuse)

View File

@ -47,6 +47,7 @@ makedepends="
lvm2-dev
nss-dev
openldap-dev
krb5-dev
parted
procps
python-dev

View File

@ -228,6 +228,8 @@ BuildRequires: keyutils-devel
BuildRequires: libopenssl-devel
BuildRequires: lsb-release
BuildRequires: openldap2-devel
BuildRequires: krb5
BuildRequires: krb5-devel
BuildRequires: cunit-devel
BuildRequires: python%{_python_buildid}-base
BuildRequires: python%{_python_buildid}-Cython < 0.29
@ -245,6 +247,7 @@ BuildRequires: keyutils-libs-devel
BuildRequires: libibverbs-devel
BuildRequires: librdmacm-devel
BuildRequires: openldap-devel
BuildRequires: krb5-devel
BuildRequires: openssl-devel
BuildRequires: CUnit-devel
BuildRequires: redhat-lsb-core

View File

@ -0,0 +1,22 @@
# - Find KRB5/GSSAPI C Libraries
#
# GSSAPI_FOUND - True if found.
# GSSAPI_INCLUDE_DIR - Path to the KRB5/gssapi include directory
# GSSAPI_LIBRARIES - Paths to the KRB5/gssapi libraries
find_path(GSSAPI_INCLUDE_DIR gssapi.h PATHS
/usr/include
/opt/local/include
/usr/local/include)
find_library(GSSAPI_KRB5_LIBRARY gssapi_krb5)
include(FindPackageHandleStandardArgs)
find_package_handle_standard_args(GSSApi DEFAULT_MSG
GSSAPI_INCLUDE_DIR GSSAPI_KRB5_LIBRARY)
set(GSSAPI_LIBRARIES ${GSSAPI_KRB5_LIBRARY})
mark_as_advanced(
GSSAPI_INCLUDE_DIR GSSAPI_KRB5_LIBRARY)

1
debian/control vendored
View File

@ -37,6 +37,7 @@ Build-Depends: bc,
librdmacm-dev,
libkeyutils-dev,
libldap2-dev,
libkrb5-dev,
libleveldb-dev,
liblttng-ust-dev,
liblz4-dev (>= 0.0~r131),

1094
doc/dev/ceph_krb_auth.rst Normal file

File diff suppressed because it is too large Load Diff

View File

@ -364,6 +364,7 @@ set(ceph_common_deps
${Backtrace_LIBRARIES}
${BLKIN_LIBRARIES}
${CRYPTO_LIBS}
${GSSAPI_LIBRARIES}
${CMAKE_THREAD_LIBS_INIT}
${CMAKE_DL_LIBS})
if(HAVE_UDEV)
@ -455,7 +456,7 @@ endif()
set(librados_config_srcs
librados-config.cc)
add_executable(librados-config ${librados_config_srcs})
target_link_libraries(librados-config librados global ${BLKID_LIBRARIES} ${CMAKE_DL_LIBS})
target_link_libraries(librados-config librados global ${BLKID_LIBRARIES} ${CMAKE_DL_LIBS} ${GSSAPI_LIBRARIES})
install(TARGETS librados-config DESTINATION bin)
@ -477,7 +478,7 @@ add_executable(ceph-mon ${ceph_mon_srcs}
add_dependencies(ceph-mon erasure_code_plugins)
target_link_libraries(ceph-mon mon os global-static ceph-common
${EXTRALIBS}
${CMAKE_DL_LIBS})
${CMAKE_DL_LIBS} ${GSSAPI_LIBRARIES})
install(TARGETS ceph-mon DESTINATION bin)
# OSD/ObjectStore
@ -656,7 +657,7 @@ if(WITH_FUSE)
client/fuse_ll.cc)
add_executable(ceph-fuse ${ceph_fuse_srcs})
target_link_libraries(ceph-fuse ${FUSE_LIBRARIES}
client ceph-common global-static)
${GSSAPI_LIBRARIES} client ceph-common global-static)
set_target_properties(ceph-fuse PROPERTIES
COMPILE_FLAGS "-I${FUSE_INCLUDE_DIRS}"
POSITION_INDEPENDENT_CODE ${EXE_LINKER_USE_PIE})

View File

@ -14,6 +14,7 @@
#include "AuthAuthorizeHandler.h"
#include "cephx/CephxAuthorizeHandler.h"
#include "krb/KrbAuthorizeHandler.hpp"
#include "none/AuthNoneAuthorizeHandler.h"
AuthAuthorizeHandler *AuthAuthorizeHandlerRegistry::get_handler(int protocol)
@ -35,6 +36,10 @@ AuthAuthorizeHandler *AuthAuthorizeHandlerRegistry::get_handler(int protocol)
case CEPH_AUTH_CEPHX:
m_authorizers[protocol] = new CephxAuthorizeHandler();
return m_authorizers[protocol];
case CEPH_AUTH_GSS:
m_authorizers[protocol] = new KrbAuthorizeHandler();
return m_authorizers[protocol];
}
return NULL;
}

View File

@ -17,6 +17,7 @@
#include "AuthClientHandler.h"
#include "cephx/CephxClientHandler.h"
#include "krb/KrbClientHandler.hpp"
#include "none/AuthNoneClientHandler.h"
@ -29,7 +30,10 @@ AuthClientHandler::create(CephContext* cct, int proto,
return new CephxClientHandler(cct, rkeys);
case CEPH_AUTH_NONE:
return new AuthNoneClientHandler{cct};
case CEPH_AUTH_GSS:
return new KrbClientHandler(cct);
default:
return NULL;
}
}

View File

@ -34,6 +34,8 @@ AuthMethodList::AuthMethodList(CephContext *cct, std::string str)
auth_supported.push_back(CEPH_AUTH_CEPHX);
} else if (iter->compare("none") == 0) {
auth_supported.push_back(CEPH_AUTH_NONE);
} else if (iter->compare("gss") == 0) {
auth_supported.push_back(CEPH_AUTH_GSS);
} else {
auth_supported.push_back(CEPH_AUTH_UNKNOWN);
lderr(cct) << "WARNING: unknown auth protocol defined: " << *iter << dendl;

View File

@ -14,6 +14,7 @@
#include "AuthServiceHandler.h"
#include "cephx/CephxServiceHandler.h"
#include "krb/KrbServiceHandler.hpp"
#include "none/AuthNoneServiceHandler.h"
#define dout_subsys ceph_subsys_auth
@ -26,6 +27,8 @@ AuthServiceHandler *get_auth_service_handler(int type, CephContext *cct, KeyServ
return new CephxServiceHandler(cct, ks);
case CEPH_AUTH_NONE:
return new AuthNoneServiceHandler(cct);
case CEPH_AUTH_GSS:
return new KrbServiceHandler(cct, ks);
}
return NULL;
}

View File

@ -15,6 +15,7 @@
#include "common/debug.h"
#include "AuthSessionHandler.h"
#include "cephx/CephxSessionHandler.h"
#include "krb/KrbSessionHandler.hpp"
#include "none/AuthNoneSessionHandler.h"
#include "unknown/AuthUnknownSessionHandler.h"
@ -39,6 +40,8 @@ AuthSessionHandler *get_auth_session_handler(CephContext *cct, int protocol, Cry
return new AuthNoneSessionHandler(cct, key);
case CEPH_AUTH_UNKNOWN:
return new AuthUnknownSessionHandler(cct, key);
case CEPH_AUTH_GSS:
return new KrbSessionHandler(cct, key);
}
return NULL;
}

View File

@ -10,6 +10,10 @@ set(auth_srcs
cephx/CephxClientHandler.cc
cephx/CephxProtocol.cc
cephx/CephxSessionHandler.cc
krb/KrbAuthorizeHandler.cpp
krb/KrbClientHandler.cpp
krb/KrbProtocol.cpp
krb/KrbSessionHandler.hpp
none/AuthNoneAuthorizeHandler.cc
unknown/AuthUnknownAuthorizeHandler.cc)

View File

@ -0,0 +1,51 @@
// -*- 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) 2018 SUSE LLC.
* Author: Daniel Oliveira <doliveira@suse.com>
*
* 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 "KrbAuthorizeHandler.hpp"
#include "common/debug.h"
#define dout_subsys ceph_subsys_auth
bool KrbAuthorizeHandler::verify_authorizer(CephContext* ceph_ctx,
KeyStore* keys,
bufferlist& authorizer_data,
bufferlist& authorizer_reply,
EntityName& entity_name,
uint64_t& global_id,
AuthCapsInfo& caps_info,
CryptoKey& session_key,
std::unique_ptr<
AuthAuthorizerChallenge>* challenge)
{
auto itr(authorizer_data.cbegin());
try {
uint8_t value = (1);
using ceph::decode;
decode(value, itr);
decode(entity_name, itr);
decode(global_id, itr);
} catch (const buffer::error& err) {
ldout(ceph_ctx, 0)
<< "Error: KrbAuthorizeHandler::verify_authorizer() failed!" << dendl;
return false;
}
caps_info.allow_all = true;
return true;
}

View File

@ -0,0 +1,39 @@
// -*- 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) 2018 SUSE LLC.
* Author: Daniel Oliveira <doliveira@suse.com>
*
* 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 KRB_AUTHORIZE_HANDLER_HPP
#define KRB_AUTHORIZE_HANDLER_HPP
#include "auth/AuthAuthorizeHandler.h"
class KrbAuthorizeHandler : public AuthAuthorizeHandler {
bool verify_authorizer(CephContext*, KeyStore*,
bufferlist&, bufferlist&,
EntityName&, uint64_t&,
AuthCapsInfo&, CryptoKey&,
std::unique_ptr<
AuthAuthorizerChallenge>* = nullptr) override;
int authorizer_session_crypto() override {
return SESSION_SYMMETRIC_AUTHENTICATE;
};
~KrbAuthorizeHandler() override = default;
};
#endif //-- KRB_AUTHORIZE_HANDLER_HPP

View File

@ -0,0 +1,251 @@
// -*- 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) 2018 SUSE LLC.
* Author: Daniel Oliveira <doliveira@suse.com>
*
* 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 "KrbClientHandler.hpp"
#include <errno.h>
#include <string>
#include "KrbProtocol.hpp"
#include "auth/KeyRing.h"
#include "include/random.h"
#include "common/ceph_context.h"
#include "common/config.h"
#include "common/dout.h"
#define dout_subsys ceph_subsys_auth
#undef dout_prefix
#define dout_prefix *_dout << "krb5/gssapi client request: "
struct AuthAuthorizer;
AuthAuthorizer*
KrbClientHandler::build_authorizer(uint32_t service_id) const
{
ldout(cct, 20)
<< "KrbClientHandler::build_authorizer(): Service: "
<< ceph_entity_type_name(service_id) << dendl;
KrbAuthorizer* krb_auth = new KrbAuthorizer();
if (krb_auth) {
krb_auth->build_authorizer(cct->_conf->name, global_id);
}
return krb_auth;
}
KrbClientHandler::~KrbClientHandler()
{
OM_uint32 gss_minor_status(0);
gss_release_name(&gss_minor_status, &m_gss_client_name);
gss_release_name(&gss_minor_status, &m_gss_service_name);
gss_release_cred(&gss_minor_status, &m_gss_credentials);
gss_delete_sec_context(&gss_minor_status, &m_gss_sec_ctx, GSS_C_NO_BUFFER);
gss_release_buffer(&gss_minor_status,
static_cast<gss_buffer_t>(&m_gss_buffer_out));
}
int KrbClientHandler::build_request(bufferlist& buff_list) const
{
ldout(cct, 20)
<< "KrbClientHandler::build_request() " << dendl;
KrbTokenBlob krb_token;
KrbRequest krb_request;
krb_request.m_request_type =
static_cast<int>(GSSAuthenticationRequest::GSS_TOKEN);
using ceph::encode;
encode(krb_request, buff_list);
if (m_gss_buffer_out.length != 0) {
krb_token.m_token_blob.append(buffer::create_static(
m_gss_buffer_out.length,
reinterpret_cast<char*>
(m_gss_buffer_out.value)));
encode(krb_token, buff_list);
ldout(cct, 20)
<< "KrbClientHandler::build_request() : Token Blob: " << "\n";
krb_token.m_token_blob.hexdump(*_dout);
*_dout << dendl;
}
return 0;
}
int KrbClientHandler::handle_response(int ret,
bufferlist::const_iterator& buff_list)
{
auto result(ret);
gss_buffer_desc gss_buffer_in = {0, nullptr};
gss_OID_set_desc gss_mechs_wanted = {0, nullptr};
OM_uint32 gss_major_status(0);
OM_uint32 gss_minor_status(0);
OM_uint32 gss_wanted_flags(GSS_C_MUTUAL_FLAG |
GSS_C_INTEG_FLAG);
OM_uint32 gss_result_flags(0);
ldout(cct, 20)
<< "KrbClientHandler::handle_response() " << dendl;
if (result < 0) {
return result;
}
gss_mechs_wanted.elements = const_cast<gss_OID>(&GSS_API_SPNEGO_OID_PTR);
gss_mechs_wanted.count = 1;
KrbResponse krb_response;
using ceph::decode;
decode(krb_response, buff_list);
if (m_gss_credentials == GSS_C_NO_CREDENTIAL) {
gss_buffer_desc krb_client_name_buff = {0, nullptr};
gss_OID krb_client_type = GSS_C_NT_USER_NAME;
std::string krb_client_name(cct->_conf->name.to_str());
krb_client_name_buff.length = krb_client_name.length();
krb_client_name_buff.value = (const_cast<char*>(krb_client_name.c_str()));
if (cct->_conf->name.get_type() == CEPH_ENTITY_TYPE_CLIENT) {
gss_major_status = gss_import_name(&gss_minor_status,
&gss_buffer_in,
krb_client_type,
&m_gss_client_name);
if (gss_major_status != GSS_S_COMPLETE) {
auto status_str(gss_auth_show_status(gss_major_status,
gss_minor_status));
ldout(cct, 0)
<< "ERROR: KrbClientHandler::handle_response() "
"[gss_import_name(gss_client_name)] failed! "
<< gss_major_status << " "
<< gss_minor_status << " "
<< status_str
<< dendl;
}
}
gss_major_status = gss_acquire_cred(&gss_minor_status,
m_gss_client_name,
0,
&gss_mechs_wanted,
GSS_C_INITIATE,
&m_gss_credentials,
nullptr,
nullptr);
if (gss_major_status != GSS_S_COMPLETE) {
auto status_str(gss_auth_show_status(gss_major_status,
gss_minor_status));
ldout(cct, 20)
<< "ERROR: KrbClientHandler::handle_response() "
"[gss_acquire_cred()] failed! "
<< gss_major_status << " "
<< gss_minor_status << " "
<< status_str
<< dendl;
return (-EPERM);
}
gss_buffer_desc krb_input_name_buff = {0, nullptr};
gss_OID krb_input_type = GSS_C_NT_HOSTBASED_SERVICE;
std::string gss_target_name(cct->_conf.get_val<std::string>
("gss_target_name"));
krb_input_name_buff.length = gss_target_name.length();
krb_input_name_buff.value = (const_cast<char*>(gss_target_name.c_str()));
gss_major_status = gss_import_name(&gss_minor_status,
&krb_input_name_buff,
krb_input_type,
&m_gss_service_name);
if (gss_major_status != GSS_S_COMPLETE) {
auto status_str(gss_auth_show_status(gss_major_status,
gss_minor_status));
ldout(cct, 0)
<< "ERROR: KrbClientHandler::handle_response() "
"[gss_import_name(gss_service_name)] failed! "
<< gss_major_status << " "
<< gss_minor_status << " "
<< status_str
<< dendl;
}
} else {
KrbTokenBlob krb_token;
using ceph::decode;
decode(krb_token, buff_list);
ldout(cct, 20)
<< "KrbClientHandler::handle_response() : Token Blob: " << "\n";
krb_token.m_token_blob.hexdump(*_dout);
*_dout << dendl;
gss_buffer_in.length = krb_token.m_token_blob.length();
gss_buffer_in.value = krb_token.m_token_blob.c_str();
}
const gss_OID gss_mech_type = gss_mechs_wanted.elements;
if (m_gss_buffer_out.length != 0) {
gss_release_buffer(&gss_minor_status,
static_cast<gss_buffer_t>(&m_gss_buffer_out));
}
gss_major_status = gss_init_sec_context(&gss_minor_status,
m_gss_credentials,
&m_gss_sec_ctx,
m_gss_service_name,
gss_mech_type,
gss_wanted_flags,
0,
nullptr,
&gss_buffer_in,
nullptr,
&m_gss_buffer_out,
&gss_result_flags,
nullptr);
switch (gss_major_status) {
case GSS_S_CONTINUE_NEEDED:
ldout(cct, 20)
<< "KrbClientHandler::handle_response() : "
"[gss_init_sec_context(GSS_S_CONTINUE_NEEDED)] " << dendl;
result = (-EAGAIN);
break;
case GSS_S_COMPLETE:
ldout(cct, 20)
<< "KrbClientHandler::handle_response() : "
"[gss_init_sec_context(GSS_S_COMPLETE)] " << dendl;
result = 0;
break;
default:
auto status_str(gss_auth_show_status(gss_major_status,
gss_minor_status));
ldout(cct, 0)
<< "ERROR: KrbClientHandler::handle_response() "
"[gss_init_sec_context()] failed! "
<< gss_major_status << " "
<< gss_minor_status << " "
<< status_str
<< dendl;
result = (-EPERM);
break;
}
return result;
}

View File

@ -0,0 +1,78 @@
// -*- 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) 2018 SUSE LLC.
* Author: Daniel Oliveira <doliveira@suse.com>
*
* 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 KRB_CLIENT_HANDLER_HPP
#define KRB_CLIENT_HANDLER_HPP
#include "auth/AuthClientHandler.h"
#include "auth/RotatingKeyRing.h"
#include "KrbProtocol.hpp"
#include <gssapi.h>
#include <gssapi/gssapi_generic.h>
#include <gssapi/gssapi_krb5.h>
#include <gssapi/gssapi_ext.h>
class CephContext;
class Keyring;
class KrbClientHandler : public AuthClientHandler {
public:
KrbClientHandler(CephContext* ceph_ctx = nullptr)
: AuthClientHandler(ceph_ctx) {
reset();
}
~KrbClientHandler() override;
int get_protocol() const override { return CEPH_AUTH_GSS; }
void reset() override {
m_gss_client_name = GSS_C_NO_NAME;
m_gss_service_name = GSS_C_NO_NAME;
m_gss_credentials = GSS_C_NO_CREDENTIAL;
m_gss_sec_ctx = GSS_C_NO_CONTEXT;
m_gss_buffer_out = {0, 0};
}
void prepare_build_request() override { };
int build_request(bufferlist& buff_list) const override;
int handle_response(int ret,
bufferlist::const_iterator& buff_list) override;
bool build_rotating_request(bufferlist& buff_list) const override {
return false;
}
AuthAuthorizer* build_authorizer(uint32_t service_id) const override;
bool need_tickets() override { return false; }
void set_global_id(uint64_t guid) override { global_id = guid; }
private:
gss_name_t m_gss_client_name;
gss_name_t m_gss_service_name;
gss_cred_id_t m_gss_credentials;
gss_ctx_id_t m_gss_sec_ctx;
gss_buffer_desc m_gss_buffer_out;
protected:
void validate_tickets() override { }
};
#endif //-- KRB_CLIENT_HANDLER_HPP

View File

@ -0,0 +1,86 @@
// -*- 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) 2018 SUSE LLC.
* Author: Daniel Oliveira <doliveira@suse.com>
*
* 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 "KrbProtocol.hpp"
#include "common/Clock.h"
#include "common/config.h"
#include "common/debug.h"
#include "include/buffer.h"
#define dout_subsys ceph_subsys_auth
#undef dout_prefix
#define dout_prefix *_dout << "krb5/gssapi protocol: "
std::string gss_auth_show_status(const OM_uint32 gss_major_status,
const OM_uint32 gss_minor_status)
{
const std::string STR_DOT(".");
const std::string STR_BLANK(" ");
gss_buffer_desc gss_str_status = {0, nullptr};
OM_uint32 gss_maj_status(0);
OM_uint32 gss_min_status(0);
OM_uint32 gss_ctx_message(-1);
std::string str_status("");
const auto gss_complete_status_str_format = [&](const uint32_t gss_status) {
if (gss_status == GSS_S_COMPLETE) {
std::string str_tmp("");
str_tmp.append(reinterpret_cast<char*>(gss_str_status.value),
gss_str_status.length);
str_tmp += STR_DOT;
if (gss_ctx_message != 0) {
str_tmp += STR_BLANK;
}
return str_tmp;
}
return STR_BLANK;
};
while (gss_ctx_message != 0) {
gss_maj_status = gss_display_status(&gss_min_status,
gss_major_status,
GSS_C_GSS_CODE,
GSS_C_NO_OID,
&gss_ctx_message,
&gss_str_status);
if (gss_maj_status == GSS_S_COMPLETE) {
str_status += gss_complete_status_str_format(gss_maj_status);
gss_release_buffer(&gss_min_status, &gss_str_status);
}
}
if (gss_major_status == GSS_S_FAILURE) {
gss_ctx_message = -1;
while (gss_ctx_message != 0) {
gss_maj_status = gss_display_status(&gss_min_status,
gss_minor_status,
GSS_C_MECH_CODE,
const_cast<gss_OID>(&GSS_API_KRB5_OID_PTR),
&gss_ctx_message,
&gss_str_status);
if (gss_maj_status == GSS_S_COMPLETE) {
str_status += gss_complete_status_str_format(gss_maj_status);
gss_release_buffer(&gss_min_status, &gss_str_status);
}
}
}
return str_status;
}

View File

@ -0,0 +1,159 @@
// -*- 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) 2018 SUSE LLC.
* Author: Daniel Oliveira <doliveira@suse.com>
*
* 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 KRB_PROTOCOL_HPP
#define KRB_PROTOCOL_HPP
#include "auth/Auth.h"
#include <errno.h>
#include <gssapi.h>
#include <gssapi/gssapi_generic.h>
#include <gssapi/gssapi_krb5.h>
#include <gssapi/gssapi_ext.h>
#include <map>
#include <sstream>
#include <string>
/*
Kerberos Version 5 GSS-API Mechanism
OID {1.2.840.113554.1.2.2}
RFC https://tools.ietf.org/html/rfc1964
*/
static const gss_OID_desc GSS_API_KRB5_OID_PTR =
{ 9, (void *)"\052\206\110\206\367\022\001\002\002" };
/*
Kerberos Version 5 GSS-API Mechanism
Simple and Protected GSS-API Negotiation Mechanism
OID {1.3.6.1.5.5.2}
RFC https://tools.ietf.org/html/rfc4178
*/
static const gss_OID_desc GSS_API_SPNEGO_OID_PTR =
{6, (void *)"\x2b\x06\x01\x05\x05\x02"};
static const std::string KRB_SERVICE_NAME("kerberos/gssapi");
static const std::string GSS_API_SPNEGO_OID("{1.3.6.1.5.5.2}");
static const std::string GSS_API_KRB5_OID("{1.2.840.113554.1.2.2}");
enum class GSSAuthenticationRequest {
GSS_CRYPTO_ERR = 1,
GSS_MUTUAL = 0x100,
GSS_TOKEN = 0x200,
GSS_REQUEST_MASK = 0x0F00
};
enum class GSSKeyExchange {
USERAUTH_GSSAPI_RESPONSE = 70,
USERAUTH_GSSAPI_TOKEN,
USERAUTH_GSSAPI_EXCHANGE_COMPLETE,
USERAUTH_GSSAPI_ERROR,
USERAUTH_GSSAPI_ERRTOK,
USERAUTH_GSSAPI_MIC,
};
static constexpr auto CEPH_GSS_OIDTYPE(0x07);
struct AuthAuthorizer;
class KrbAuthorizer : public AuthAuthorizer {
public:
KrbAuthorizer() : AuthAuthorizer(CEPH_AUTH_GSS) { }
~KrbAuthorizer() = default;
bool build_authorizer(const EntityName& entity_name,
const uint64_t guid) {
uint8_t value = (1);
using ceph::encode;
encode(value, bl, 0);
encode(entity_name, bl, 0);
encode(guid, bl, 0);
return false;
}
bool verify_reply(bufferlist::const_iterator& buff_list) override {
return true;
}
bool add_challenge(CephContext* ceph_ctx,
bufferlist& buff_list) override {
return true;
}
};
class KrbRequest {
public:
void decode(bufferlist::const_iterator& buff_list) {
using ceph::decode;
decode(m_request_type, buff_list);
}
void encode(bufferlist& buff_list) const {
using ceph::encode;
encode(m_request_type, buff_list);
}
uint16_t m_request_type;
};
WRITE_CLASS_ENCODER(KrbRequest);
class KrbResponse {
public:
void decode(bufferlist::const_iterator& buff_list) {
using ceph::decode;
decode(m_response_type, buff_list);
}
void encode(bufferlist& buff_list) const {
using ceph::encode;
encode(m_response_type, buff_list);
}
uint16_t m_response_type;
};
WRITE_CLASS_ENCODER(KrbResponse);
class KrbTokenBlob {
public:
void decode(bufferlist::const_iterator& buff_list) {
uint8_t value = (0);
using ceph::decode;
decode(value, buff_list);
decode(m_token_blob, buff_list);
}
void encode(bufferlist& buff_list) const {
uint8_t value = (1);
using ceph::encode;
encode(value, buff_list, 0);
encode(m_token_blob, buff_list, 0);
}
bufferlist m_token_blob;
};
WRITE_CLASS_ENCODER(KrbTokenBlob);
std::string gss_auth_show_status(const OM_uint32 gss_major_status,
const OM_uint32 gss_minor_status);
#endif //-- KRB_PROTOCOL_HPP

View File

@ -0,0 +1,223 @@
// -*- 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) 2018 SUSE LLC.
* Author: Daniel Oliveira <doliveira@suse.com>
*
* 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 "KrbServiceHandler.hpp"
#include "KrbProtocol.hpp"
#include <errno.h>
#include <sstream>
#include "common/config.h"
#include "common/debug.h"
#define dout_subsys ceph_subsys_auth
#undef dout_prefix
#define dout_prefix *_dout << "krb5/gssapi service: " << entity_name << " : "
int KrbServiceHandler::handle_request(bufferlist::const_iterator& indata,
bufferlist& buff_list,
uint64_t& global_id,
AuthCapsInfo& caps)
{
auto result(0);
gss_buffer_desc gss_buffer_in = {0, nullptr};
gss_name_t gss_client_name = GSS_C_NO_NAME;
gss_OID gss_object_id = {0};
OM_uint32 gss_major_status(0);
OM_uint32 gss_minor_status(0);
OM_uint32 gss_result_flags(0);
std::string status_str(" ");
ldout(cct, 20)
<< "KrbServiceHandler::handle_request() " << dendl;
KrbRequest krb_request;
KrbTokenBlob krb_token;
using ceph::decode;
decode(krb_request, indata);
decode(krb_token, indata);
gss_buffer_in.length = krb_token.m_token_blob.length();
gss_buffer_in.value = krb_token.m_token_blob.c_str();
ldout(cct, 20)
<< "KrbClientHandler::handle_request() : Token Blob: "
<< "\n";
krb_token.m_token_blob.hexdump(*_dout);
*_dout << dendl;
if (m_gss_buffer_out.length != 0) {
gss_release_buffer(&gss_minor_status,
static_cast<gss_buffer_t>(&m_gss_buffer_out));
}
gss_major_status = gss_accept_sec_context(&gss_minor_status,
&m_gss_sec_ctx,
m_gss_credentials,
&gss_buffer_in,
GSS_C_NO_CHANNEL_BINDINGS,
&gss_client_name,
&gss_object_id,
&m_gss_buffer_out,
&gss_result_flags,
nullptr,
nullptr);
switch (gss_major_status) {
case GSS_S_CONTINUE_NEEDED:
{
ldout(cct, 20)
<< "KrbServiceHandler::handle_response() : "
"[KrbServiceHandler(GSS_S_CONTINUE_NEEDED)] " << dendl;
result = 0;
break;
}
case GSS_S_COMPLETE:
{
result = 0;
ldout(cct, 20)
<< "KrbServiceHandler::handle_response() : "
"[KrbServiceHandler(GSS_S_COMPLETE)] " << dendl;
if (!m_key_server->get_service_caps(entity_name,
CEPH_ENTITY_TYPE_MON,
caps)) {
result = (-EACCES);
ldout(cct, 0)
<< "KrbServiceHandler::handle_response() : "
"ERROR: Could not get MONITOR CAPS : " << entity_name << dendl;
} else {
if (!caps.caps.c_str()) {
result = (-EACCES);
ldout(cct, 0)
<< "KrbServiceHandler::handle_response() : "
"ERROR: MONITOR CAPS invalid : " << entity_name << dendl;
}
}
break;
}
default:
{
status_str = gss_auth_show_status(gss_major_status,
gss_minor_status);
ldout(cct, 0)
<< "ERROR: KrbServiceHandler::handle_response() "
"[gss_accept_sec_context()] failed! "
<< gss_major_status << " "
<< gss_minor_status << " "
<< status_str
<< dendl;
result = (-EPERM);
break;
}
}
if (m_gss_buffer_out.length != 0) {
KrbResponse krb_response;
KrbTokenBlob krb_token;
krb_response.m_response_type =
static_cast<int>(GSSAuthenticationRequest::GSS_TOKEN);
using ceph::encode;
encode(krb_response, buff_list);
krb_token.m_token_blob.append(buffer::create_static(
m_gss_buffer_out.length,
reinterpret_cast<char*>
(m_gss_buffer_out.value)));
encode(krb_token, buff_list);
ldout(cct, 20)
<< "KrbServiceHandler::handle_request() : Token Blob: " << "\n";
krb_token.m_token_blob.hexdump(*_dout);
*_dout << dendl;
}
gss_release_name(&gss_minor_status, &gss_client_name);
return result;
}
int KrbServiceHandler::start_session(EntityName& name,
bufferlist::const_iterator& indata,
bufferlist& buff_list,
AuthCapsInfo& caps)
{
gss_buffer_desc gss_buffer_in = {0, nullptr};
gss_OID gss_object_id = GSS_C_NT_HOSTBASED_SERVICE;
gss_OID_set gss_mechs_wanted = GSS_C_NO_OID_SET;
OM_uint32 gss_major_status(0);
OM_uint32 gss_minor_status(0);
std::string gss_service_name(cct->_conf.get_val<std::string>
("gss_target_name"));
gss_buffer_in.length = gss_service_name.length();
gss_buffer_in.value = (const_cast<char*>(gss_service_name.c_str()));
entity_name = name;
gss_major_status = gss_import_name(&gss_minor_status,
&gss_buffer_in,
gss_object_id,
&m_gss_service_name);
if (gss_major_status != GSS_S_COMPLETE) {
auto status_str(gss_auth_show_status(gss_major_status,
gss_minor_status));
ldout(cct, 0)
<< "ERROR: KrbServiceHandler::start_session() "
"[gss_import_name(gss_client_name)] failed! "
<< gss_major_status << " "
<< gss_minor_status << " "
<< status_str
<< dendl;
}
gss_major_status = gss_acquire_cred(&gss_minor_status,
m_gss_service_name,
0,
gss_mechs_wanted,
GSS_C_ACCEPT,
&m_gss_credentials,
nullptr,
nullptr);
if (gss_major_status != GSS_S_COMPLETE) {
auto status_str(gss_auth_show_status(gss_major_status,
gss_minor_status));
ldout(cct, 0)
<< "ERROR: KrbServiceHandler::start_session() "
"[gss_acquire_cred()] failed! "
<< gss_major_status << " "
<< gss_minor_status << " "
<< status_str
<< dendl;
return (-EPERM);
} else {
KrbResponse krb_response;
krb_response.m_response_type =
static_cast<int>(GSSAuthenticationRequest::GSS_MUTUAL);
using ceph::encode;
encode(krb_response, buff_list);
return (CEPH_AUTH_GSS);
}
}
KrbServiceHandler::~KrbServiceHandler()
{
OM_uint32 gss_minor_status(0);
gss_release_name(&gss_minor_status, &m_gss_service_name);
gss_release_cred(&gss_minor_status, &m_gss_credentials);
gss_delete_sec_context(&gss_minor_status, &m_gss_sec_ctx, GSS_C_NO_BUFFER);
gss_release_buffer(&gss_minor_status, static_cast<gss_buffer_t>(&m_gss_buffer_out));
}

View File

@ -0,0 +1,60 @@
// -*- 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) 2018 SUSE LLC.
* Author: Daniel Oliveira <doliveira@suse.com>
*
* 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 KRB_SERVICE_HANDLER_HPP
#define KRB_SERVICE_HANDLER_HPP
#include "auth/AuthServiceHandler.h"
#include "auth/Auth.h"
#include "auth/cephx/CephxKeyServer.h"
#include <gssapi.h>
#include <gssapi/gssapi_generic.h>
#include <gssapi/gssapi_krb5.h>
#include <gssapi/gssapi_ext.h>
class KrbServiceHandler : public AuthServiceHandler {
public:
explicit KrbServiceHandler(CephContext* ceph_ctx, KeyServer* kserver) :
AuthServiceHandler(ceph_ctx),
m_gss_buffer_out({0, nullptr}),
m_gss_credentials(GSS_C_NO_CREDENTIAL),
m_gss_sec_ctx(GSS_C_NO_CONTEXT),
m_gss_service_name(GSS_C_NO_NAME),
m_key_server(kserver) { }
~KrbServiceHandler();
int handle_request(bufferlist::const_iterator& indata,
bufferlist& buff_list,
uint64_t& global_id,
AuthCapsInfo& caps) override;
int start_session(EntityName& name,
bufferlist::const_iterator& indata,
bufferlist& buff_list,
AuthCapsInfo& caps) override;
private:
gss_buffer_desc m_gss_buffer_out;
gss_cred_id_t m_gss_credentials;
gss_ctx_id_t m_gss_sec_ctx;
gss_name_t m_gss_service_name;
KeyServer* m_key_server;
};
#endif //-- KRB_SERVICE_HANDLER_HPP

View File

@ -0,0 +1,54 @@
// -*- 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) 2018 SUSE LLC.
* Author: Daniel Oliveira <doliveira@suse.com>
*
* 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 KRB_SESSION_HANDLER_HPP
#define KRB_SESSION_HANDLER_HPP
#include "auth/AuthSessionHandler.h"
#include "auth/Auth.h"
#include "KrbProtocol.hpp"
#include <errno.h>
#include <sstream>
#include "common/config.h"
#include "include/ceph_features.h"
#include "msg/Message.h"
#define dout_subsys ceph_subsys_auth
class CephContext;
class Message;
class KrbSessionHandler : public AuthSessionHandler {
public:
KrbSessionHandler(CephContext* ceph_ctx, CryptoKey session_key) :
AuthSessionHandler(ceph_ctx, CEPH_AUTH_GSS, session_key) { }
~KrbSessionHandler() override = default;
bool no_security() override { return true; }
int sign_message(Message* msg) override { return 0; }
int check_message_signature(Message* msg) override { return 0; }
int encrypt_message(Message* msg) override { return 0; }
int decrypt_message(Message* msg) override { return 0; }
private:
};
#endif //-- KRB_SESSION_HANDLER_HPP

View File

@ -5021,7 +5021,18 @@ std::vector<Option> get_global_options() {
.set_description("Method used to predict device failures")
.set_long_description("To disable prediction, use 'none', 'local' uses a prediction model that runs inside the mgr daemon. 'cloud' will share metrics with a cloud service and query the service for devicelife expectancy."),
/* KRB Authentication. */
Option("gss_ktab_client_file", Option::TYPE_STR, Option::LEVEL_ADVANCED)
.set_default("/var/lib/ceph/$name/gss_client_$name.ktab")
.set_description("GSS/KRB5 Keytab file for client authentication")
.add_service({"mon", "osd"})
.set_long_description("This sets the full path for the GSS/Kerberos client keytab file location."),
Option("gss_target_name", Option::TYPE_STR, Option::LEVEL_ADVANCED)
.set_default("ceph")
.set_description("")
.add_service({"mon", "osd"})
.set_long_description("This sets the gss target service name."),
});
}

View File

@ -73,6 +73,16 @@ struct ceph_dir_layout {
#define CEPH_AUTH_NONE 0x1
#define CEPH_AUTH_CEPHX 0x2
/* For options with "_", like: GSS_GSS
which means: Mode/Protocol to validate "authentication_authorization",
where:
- Authentication: Verifying the identity of an entity.
- Authorization: Verifying that an authenticated entity has
the right to access a particular resource.
*/
#define CEPH_AUTH_GSS 0x4
#define CEPH_AUTH_GSS_GSS CEPH_AUTH_GSS
#define CEPH_AUTH_UID_DEFAULT ((__u64) -1)

View File

@ -41,7 +41,8 @@ endif()
target_link_libraries(librados PRIVATE
rados_cxx librados_impl
osdc ceph-common cls_lock_client
${BLKID_LIBRARIES} ${CRYPTO_LIBS} ${EXTRALIBS})
${BLKID_LIBRARIES} ${CRYPTO_LIBS} ${EXTRALIBS} ${GSSAPI_LIBRARIES})
target_link_libraries(librados ${rados_libs})
install(TARGETS librados DESTINATION ${CMAKE_INSTALL_LIBDIR})
# C++ API

View File

@ -161,7 +161,7 @@ target_link_libraries(librbd PRIVATE
ceph-common
pthread
${CMAKE_DL_LIBS}
${EXTRALIBS})
${EXTRALIBS} ${GSSAPI_LIBRARIES})
if(HAVE_UDEV)
target_link_libraries(librbd PRIVATE
udev)

View File

@ -66,6 +66,7 @@ MDSDaemon::MDSDaemon(std::string_view n, Messenger *m, MonClient *mc) :
mds_lock("MDSDaemon::mds_lock"),
stopping(false),
timer(m->cct, mds_lock),
gss_ktfile_client(m->cct->_conf.get_val<std::string>("gss_ktab_client_file")),
beacon(m->cct, mc, n),
authorize_handler_cluster_registry(new AuthAuthorizeHandlerRegistry(m->cct,
m->cct->_conf->auth_supported.empty() ?
@ -88,6 +89,21 @@ MDSDaemon::MDSDaemon(std::string_view n, Messenger *m, MonClient *mc) :
orig_argv = NULL;
clog = log_client.create_channel();
if (!gss_ktfile_client.empty()) {
// Assert we can export environment variable
/*
The default client keytab is used, if it is present and readable,
to automatically obtain initial credentials for GSSAPI client
applications. The principal name of the first entry in the client
keytab is used by default when obtaining initial credentials.
1. The KRB5_CLIENT_KTNAME environment variable.
2. The default_client_keytab_name profile variable in [libdefaults].
3. The hardcoded default, DEFCKTNAME.
*/
const int32_t set_result(setenv("KRB5_CLIENT_KTNAME",
gss_ktfile_client.c_str(), 1));
ceph_assert(set_result == 0);
}
monc->set_messenger(messenger);

View File

@ -51,7 +51,7 @@ class MDSDaemon : public Dispatcher, public md_config_obs_t {
bool stopping;
SafeTimer timer;
std::string gss_ktfile_client{};
mono_time get_starttime() const {
return starttime;

View File

@ -27,7 +27,7 @@ target_link_libraries(ceph-mgr
osdc client heap_profiler
global-static ceph-common
Boost::python${MGR_PYTHON_VERSION_MAJOR}${MGR_PYTHON_VERSION_MINOR}
${MGR_PYTHON_LIBRARIES} ${CMAKE_DL_LIBS})
${MGR_PYTHON_LIBRARIES} ${CMAKE_DL_LIBS} ${GSSAPI_LIBRARIES})
set_target_properties(ceph-mgr PROPERTIES
POSITION_INDEPENDENT_CODE ${EXE_LINKER_USE_PIE})
install(TARGETS ceph-mgr DESTINATION bin)

View File

@ -2,6 +2,7 @@ set(lib_mon_srcs
${CMAKE_SOURCE_DIR}/src/auth/cephx/CephxKeyServer.cc
${CMAKE_SOURCE_DIR}/src/auth/cephx/CephxServiceHandler.cc
${CMAKE_SOURCE_DIR}/src/auth/AuthServiceHandler.cc
${CMAKE_SOURCE_DIR}/src/auth/krb/KrbServiceHandler.cpp
${osd_mon_files}
Paxos.cc
PaxosService.cc

View File

@ -165,6 +165,7 @@ private:
bool initialized;
bool stopping = false;
bool no_keyring_disabled_cephx;
bool no_ktfile_disabled_krb;
LogClient *log_client;
bool more_log_pending;

View File

@ -146,9 +146,10 @@ Monitor::Monitor(CephContext* cct_, string nm, MonitorDBStore *s,
cct->_conf->auth_cluster_required : cct->_conf->auth_supported),
auth_service_required(cct,
cct->_conf->auth_supported.empty() ?
cct->_conf->auth_service_required : cct->_conf->auth_supported ),
cct->_conf->auth_service_required : cct->_conf->auth_supported),
mgr_messenger(mgr_m),
mgr_client(cct_, mgr_m),
gss_ktfile_client(cct->_conf.get_val<std::string>("gss_ktab_client_file")),
store(s),
state(STATE_PROBING),
@ -185,6 +186,22 @@ Monitor::Monitor(CephContext* cct_, string nm, MonitorDBStore *s,
update_log_clients();
if (!gss_ktfile_client.empty()) {
// Assert we can export environment variable
/*
The default client keytab is used, if it is present and readable,
to automatically obtain initial credentials for GSSAPI client
applications. The principal name of the first entry in the client
keytab is used by default when obtaining initial credentials.
1. The KRB5_CLIENT_KTNAME environment variable.
2. The default_client_keytab_name profile variable in [libdefaults].
3. The hardcoded default, DEFCKTNAME.
*/
const int32_t set_result(setenv("KRB5_CLIENT_KTNAME",
gss_ktfile_client.c_str(), 1));
ceph_assert(set_result == 0);
}
op_tracker.set_complaint_and_threshold(
g_conf().get_val<std::chrono::seconds>("mon_op_complaint_time").count(),
g_conf().get_val<int64_t>("mon_op_log_threshold"));
@ -2890,8 +2907,10 @@ void Monitor::format_command_descriptions(const std::vector<MonCommand> &command
bool Monitor::is_keyring_required()
{
return auth_cluster_required.is_supported_auth(CEPH_AUTH_CEPHX) ||
auth_service_required.is_supported_auth(CEPH_AUTH_CEPHX);
return auth_cluster_required.is_supported_auth(CEPH_AUTH_CEPHX) ||
auth_service_required.is_supported_auth(CEPH_AUTH_CEPHX) ||
auth_cluster_required.is_supported_auth(CEPH_AUTH_GSS) ||
auth_service_required.is_supported_auth(CEPH_AUTH_GSS);
}
struct C_MgrProxyCommand : public Context {

View File

@ -25,6 +25,7 @@
#include <errno.h>
#include <cmath>
#include <string>
#include "include/types.h"
#include "include/health.h"
@ -168,6 +169,7 @@ public:
Messenger *mgr_messenger;
MgrClient mgr_client;
uint64_t mgr_proxy_bytes = 0; // in-flight proxied mgr command message bytes
std::string gss_ktfile_client{};
private:
void new_tick();

View File

@ -2049,6 +2049,7 @@ OSD::OSD(CephContext *cct_, ObjectStore *store_,
tick_timer(cct, osd_lock),
tick_timer_lock("OSD::tick_timer_lock"),
tick_timer_without_osd_lock(cct, tick_timer_lock),
gss_ktfile_client(cct->_conf.get_val<std::string>("gss_ktab_client_file")),
authorize_handler_cluster_registry(new AuthAuthorizeHandlerRegistry(cct,
cct->_conf->auth_supported.empty() ?
cct->_conf->auth_cluster_required :
@ -2114,6 +2115,23 @@ OSD::OSD(CephContext *cct_, ObjectStore *store_,
&command_tp),
service(this)
{
if (!gss_ktfile_client.empty()) {
// Assert we can export environment variable
/*
The default client keytab is used, if it is present and readable,
to automatically obtain initial credentials for GSSAPI client
applications. The principal name of the first entry in the client
keytab is used by default when obtaining initial credentials.
1. The KRB5_CLIENT_KTNAME environment variable.
2. The default_client_keytab_name profile variable in [libdefaults].
3. The hardcoded default, DEFCKTNAME.
*/
const int32_t set_result(setenv("KRB5_CLIENT_KTNAME",
gss_ktfile_client.c_str(), 1));
ceph_assert(set_result == 0);
}
monc->set_messenger(client_messenger);
op_tracker.set_complaint_and_threshold(cct->_conf->osd_op_complaint_time,
cct->_conf->osd_op_log_threshold);

View File

@ -46,6 +46,7 @@
#include <atomic>
#include <map>
#include <memory>
#include <string>
#include "include/unordered_map.h"
@ -1256,6 +1257,8 @@ class OSD : public Dispatcher,
// Tick timer for those stuff that do not need osd_lock
Mutex tick_timer_lock;
SafeTimer tick_timer_without_osd_lock;
std::string gss_ktfile_client{};
public:
// config observer bits
const char** get_tracked_conf_keys() const override;

View File

@ -1,6 +1,7 @@
include(AddCephTest)
set(UNITTEST_LIBS GMock::Main GMock::GMock GTest::GTest ${CMAKE_THREAD_LIBS_INIT} ${CMAKE_DL_LIBS})
set(UNITTEST_LIBS GMock::Main GMock::GMock GTest::GTest ${CMAKE_THREAD_LIBS_INIT}
${GSSAPI_LIBRARIES} ${OPENLDAP_LIBRARIES} ${CMAKE_DL_LIBS})
add_library(unit-main OBJECT unit.cc)
target_include_directories(unit-main PRIVATE

View File

@ -12,7 +12,7 @@ target_link_libraries(radostest PUBLIC
GTest::GTest
ceph-common
json_spirit
${EXTRALIBS})
${GSSAPI_LIBRARIES} ${OPENLDAP_LIBRARIES} ${EXTRALIBS})
add_library(radostest-cxx STATIC
testcase_cxx.cc
test_cxx.cc
@ -175,7 +175,8 @@ add_executable(unittest_librados
librados.cc
)
add_ceph_unittest(unittest_librados)
target_link_libraries(unittest_librados librados ${BLKID_LIBRARIES})
target_link_libraries(unittest_librados librados ${BLKID_LIBRARIES}
${GSSAPI_LIBRARIES} ${OPENLDAP_LIBRARIES})
# unittest_librados_config
add_executable(unittest_librados_config
@ -184,6 +185,5 @@ add_executable(unittest_librados_config
add_ceph_unittest(unittest_librados_config)
target_link_libraries(unittest_librados_config
librados
${BLKID_LIBRARIES}
)
${BLKID_LIBRARIES} ${GSSAPI_LIBRARIES} ${OPENLDAP_LIBRARIES})

View File

@ -721,7 +721,6 @@ TEST_P(MessengerTest, AuthTest) {
}
ASSERT_TRUE(conn->is_connected());
ASSERT_EQ(1U, static_cast<Session*>(conn->get_priv().get())->get_count());
server_msgr->shutdown();
client_msgr->shutdown();
server_msgr->wait();

View File

@ -121,6 +121,7 @@ ec=0
hitset=""
overwrite_conf=1
cephx=1 #turn cephx on by default
gssapi_authx=0
cache=""
if [ `uname` = FreeBSD ]; then
objectstore="filestore"
@ -169,6 +170,8 @@ usage=$usage"\t-m ip:port\t\tspecify monitor address\n"
usage=$usage"\t-k keep old configuration files\n"
usage=$usage"\t-x enable cephx (on by default)\n"
usage=$usage"\t-X disable cephx\n"
usage=$usage"\t-g --gssapi enable Kerberos/GSSApi authentication\n"
usage=$usage"\t-G disable Kerberos/GSSApi authentication\n"
usage=$usage"\t--hitset <pool> <hit_set_type>: enable hitset tracking\n"
usage=$usage"\t-e : create an erasure pool\n";
usage=$usage"\t-o config\t\t add extra config parameters to all sections\n"
@ -290,6 +293,14 @@ case $1 in
-X )
cephx=0
;;
-g | --gssapi)
gssapi_authx=1
;;
-G)
gssapi_authx=0
;;
-k )
if [ ! -r $conf_fn ]; then
echo "cannot use old configuration: $conf_fn not readable." >&2
@ -483,7 +494,20 @@ EOF
lockdep = true
EOF
fi
if [ "$cephx" -ne 1 ] ; then
if [ "$cephx" -eq 1 ] ; then
wconf <<EOF
auth cluster required = cephx
auth service required = cephx
auth client required = cephx
EOF
elif [ "$gssapi_authx" -eq 1 ] ; then
wconf <<EOF
auth cluster required = gss
auth service required = gss
auth client required = gss
gss ktab client file = $CEPH_DEV_DIR/gss_\$name.keytab
EOF
else
wconf <<EOF
auth cluster required = none
auth service required = none