]> git.proxmox.com Git - ceph.git/blob - ceph/src/mon/AuthMonitor.h
4312b56071f4b7503ddee6468c58a9a616efbdf7
[ceph.git] / ceph / src / mon / AuthMonitor.h
1 // -*- mode:C++; tab-width:8; c-basic-offset:2; indent-tabs-mode:t -*-
2 // vim: ts=8 sw=2 smarttab
3 /*
4 * Ceph - scalable distributed file system
5 *
6 * Copyright (C) 2004-2006 Sage Weil <sage@newdream.net>
7 *
8 * This is free software; you can redistribute it and/or
9 * modify it under the terms of the GNU Lesser General Public
10 * License version 2.1, as published by the Free Software
11 * Foundation. See file COPYING.
12 *
13 */
14
15 #ifndef CEPH_AUTHMONITOR_H
16 #define CEPH_AUTHMONITOR_H
17
18 #include <map>
19 #include <set>
20
21 #include "global/global_init.h"
22 #include "include/ceph_features.h"
23 #include "include/types.h"
24 #include "mon/PaxosService.h"
25 #include "mon/MonitorDBStore.h"
26
27 class MAuth;
28 class KeyRing;
29 class Monitor;
30
31 #define MIN_GLOBAL_ID 0x1000
32
33 class AuthMonitor : public PaxosService {
34 public:
35 enum IncType {
36 GLOBAL_ID,
37 AUTH_DATA,
38 };
39 struct Incremental {
40 IncType inc_type;
41 uint64_t max_global_id;
42 uint32_t auth_type;
43 ceph::buffer::list auth_data;
44
45 Incremental() : inc_type(GLOBAL_ID), max_global_id(0), auth_type(0) {}
46
47 void encode(ceph::buffer::list& bl, uint64_t features=-1) const {
48 using ceph::encode;
49 ENCODE_START(2, 2, bl);
50 __u32 _type = (__u32)inc_type;
51 encode(_type, bl);
52 if (_type == GLOBAL_ID) {
53 encode(max_global_id, bl);
54 } else {
55 encode(auth_type, bl);
56 encode(auth_data, bl);
57 }
58 ENCODE_FINISH(bl);
59 }
60 void decode(ceph::buffer::list::const_iterator& bl) {
61 DECODE_START_LEGACY_COMPAT_LEN(2, 2, 2, bl);
62 __u32 _type;
63 decode(_type, bl);
64 inc_type = (IncType)_type;
65 ceph_assert(inc_type >= GLOBAL_ID && inc_type <= AUTH_DATA);
66 if (_type == GLOBAL_ID) {
67 decode(max_global_id, bl);
68 } else {
69 decode(auth_type, bl);
70 decode(auth_data, bl);
71 }
72 DECODE_FINISH(bl);
73 }
74 void dump(ceph::Formatter *f) const {
75 f->dump_int("type", inc_type);
76 f->dump_int("max_global_id", max_global_id);
77 f->dump_int("auth_type", auth_type);
78 f->dump_int("auth_data_len", auth_data.length());
79 }
80 static void generate_test_instances(std::list<Incremental*>& ls) {
81 ls.push_back(new Incremental);
82 ls.push_back(new Incremental);
83 ls.back()->inc_type = GLOBAL_ID;
84 ls.back()->max_global_id = 1234;
85 ls.push_back(new Incremental);
86 ls.back()->inc_type = AUTH_DATA;
87 ls.back()->auth_type = 12;
88 ls.back()->auth_data.append("foo");
89 }
90 };
91
92 struct auth_entity_t {
93 EntityName name;
94 EntityAuth auth;
95 };
96
97
98 private:
99 std::vector<Incremental> pending_auth;
100 uint64_t max_global_id;
101 uint64_t last_allocated_id;
102
103 // these are protected by mon->auth_lock
104 int mon_num = 0, mon_rank = 0;
105
106 bool _upgrade_format_to_dumpling();
107 bool _upgrade_format_to_luminous();
108 bool _upgrade_format_to_mimic();
109 void upgrade_format() override;
110
111 void export_keyring(KeyRing& keyring);
112 int import_keyring(KeyRing& keyring);
113
114 void push_cephx_inc(KeyServerData::Incremental& auth_inc) {
115 Incremental inc;
116 inc.inc_type = AUTH_DATA;
117 encode(auth_inc, inc.auth_data);
118 inc.auth_type = CEPH_AUTH_CEPHX;
119 pending_auth.push_back(inc);
120 }
121
122 /* validate mon/osd/mds caps; fail on unrecognized service/type */
123 bool valid_caps(const std::string& type, const std::string& caps, std::ostream *out);
124 bool valid_caps(const std::string& type, const ceph::buffer::list& bl, std::ostream *out) {
125 auto p = bl.begin();
126 std::string v;
127 try {
128 using ceph::decode;
129 decode(v, p);
130 } catch (ceph::buffer::error& e) {
131 *out << "corrupt capability encoding";
132 return false;
133 }
134 return valid_caps(type, v, out);
135 }
136 bool valid_caps(const std::vector<std::string>& caps, std::ostream *out);
137
138 void on_active() override;
139 bool should_propose(double& delay) override;
140 void get_initial_keyring(KeyRing *keyring);
141 void create_initial_keys(KeyRing *keyring);
142 void create_initial() override;
143 void update_from_paxos(bool *need_bootstrap) override;
144 void create_pending() override; // prepare a new pending
145 bool prepare_global_id(MonOpRequestRef op);
146 bool _should_increase_max_global_id(); ///< called under mon->auth_lock
147 void increase_max_global_id();
148 uint64_t assign_global_id(bool should_increase_max);
149 public:
150 uint64_t _assign_global_id(); ///< called under mon->auth_lock
151 void _set_mon_num_rank(int num, int rank); ///< called under mon->auth_lock
152
153 private:
154 // propose pending update to peers
155 void encode_pending(MonitorDBStore::TransactionRef t) override;
156 void encode_full(MonitorDBStore::TransactionRef t) override;
157 version_t get_trim_to() const override;
158
159 bool preprocess_query(MonOpRequestRef op) override; // true if processed.
160 bool prepare_update(MonOpRequestRef op) override;
161
162 bool prep_auth(MonOpRequestRef op, bool paxos_writable);
163
164 bool preprocess_command(MonOpRequestRef op);
165 bool prepare_command(MonOpRequestRef op);
166
167 bool check_rotate();
168
169 bool entity_is_pending(EntityName& entity);
170 int exists_and_matches_entity(
171 const auth_entity_t& entity,
172 bool has_secret,
173 std::stringstream& ss);
174 int exists_and_matches_entity(
175 const EntityName& name,
176 const EntityAuth& auth,
177 const std::map<std::string,ceph::buffer::list>& caps,
178 bool has_secret,
179 std::stringstream& ss);
180 int remove_entity(const EntityName &entity);
181 int add_entity(
182 const EntityName& name,
183 const EntityAuth& auth);
184
185 public:
186 AuthMonitor(Monitor &mn, Paxos &p, const std::string& service_name)
187 : PaxosService(mn, p, service_name),
188 max_global_id(0),
189 last_allocated_id(0)
190 {}
191
192 void pre_auth(MAuth *m);
193
194 void tick() override; // check state, take actions
195
196 int validate_osd_destroy(
197 int32_t id,
198 const uuid_d& uuid,
199 EntityName& cephx_entity,
200 EntityName& lockbox_entity,
201 std::stringstream& ss);
202 int do_osd_destroy(
203 const EntityName& cephx_entity,
204 const EntityName& lockbox_entity);
205
206 int do_osd_new(
207 const auth_entity_t& cephx_entity,
208 const auth_entity_t& lockbox_entity,
209 bool has_lockbox);
210 int validate_osd_new(
211 int32_t id,
212 const uuid_d& uuid,
213 const std::string& cephx_secret,
214 const std::string& lockbox_secret,
215 auth_entity_t& cephx_entity,
216 auth_entity_t& lockbox_entity,
217 std::stringstream& ss);
218
219 void dump_info(ceph::Formatter *f);
220
221 bool is_valid_cephx_key(const std::string& k) {
222 if (k.empty())
223 return false;
224
225 EntityAuth ea;
226 try {
227 ea.key.decode_base64(k);
228 return true;
229 } catch (ceph::buffer::error& e) { /* fallthrough */ }
230 return false;
231 }
232 };
233
234
235 WRITE_CLASS_ENCODER_FEATURES(AuthMonitor::Incremental)
236
237 #endif