Fix some bugs when testing opensds ansible
[stor4nfv.git] / src / 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 using namespace std;
21
22 #include "include/ceph_features.h"
23 #include "include/types.h"
24 #include "mon/PaxosService.h"
25 #include "mon/MonitorDBStore.h"
26
27 class MMonCommand;
28 struct MAuth;
29 struct MMonGlobalID;
30 class KeyRing;
31 class Monitor;
32
33 #define MIN_GLOBAL_ID 0x1000
34
35 class AuthMonitor : public PaxosService {
36 public:
37   enum IncType {
38     GLOBAL_ID,
39     AUTH_DATA,
40   };
41   struct Incremental {
42     IncType inc_type;
43     uint64_t max_global_id;
44     uint32_t auth_type;
45     bufferlist auth_data;
46
47     Incremental() : inc_type(GLOBAL_ID), max_global_id(0), auth_type(0) {}
48
49     void encode(bufferlist& bl, uint64_t features=-1) const {
50       if ((features & CEPH_FEATURE_MONENC) == 0) {
51         __u8 v = 1;
52         ::encode(v, bl);
53         __u32 _type = (__u32)inc_type;
54         ::encode(_type, bl);
55         if (_type == GLOBAL_ID) {
56           ::encode(max_global_id, bl);
57         } else {
58           ::encode(auth_type, bl);
59           ::encode(auth_data, bl);
60         }
61         return;
62       } 
63       ENCODE_START(2, 2, bl);
64       __u32 _type = (__u32)inc_type;
65       ::encode(_type, bl);
66       if (_type == GLOBAL_ID) {
67         ::encode(max_global_id, bl);
68       } else {
69         ::encode(auth_type, bl);
70         ::encode(auth_data, bl);
71       }
72       ENCODE_FINISH(bl);
73     }
74     void decode(bufferlist::iterator& bl) {
75       DECODE_START_LEGACY_COMPAT_LEN(2, 2, 2, bl);
76       __u32 _type;
77       ::decode(_type, bl);
78       inc_type = (IncType)_type;
79       assert(inc_type >= GLOBAL_ID && inc_type <= AUTH_DATA);
80       if (_type == GLOBAL_ID) {
81         ::decode(max_global_id, bl);
82       } else {
83         ::decode(auth_type, bl);
84         ::decode(auth_data, bl);
85       }
86       DECODE_FINISH(bl);
87     }
88     void dump(Formatter *f) const {
89       f->dump_int("type", inc_type);
90       f->dump_int("max_global_id", max_global_id);
91       f->dump_int("auth_type", auth_type);
92       f->dump_int("auth_data_len", auth_data.length());
93     }
94     static void generate_test_instances(list<Incremental*>& ls) {
95       ls.push_back(new Incremental);
96       ls.push_back(new Incremental);
97       ls.back()->inc_type = GLOBAL_ID;
98       ls.back()->max_global_id = 1234;
99       ls.push_back(new Incremental);
100       ls.back()->inc_type = AUTH_DATA;
101       ls.back()->auth_type = 12;
102       ls.back()->auth_data.append("foo");
103     }
104   };
105
106   struct auth_entity_t {
107     EntityName name;
108     EntityAuth auth;
109   };
110
111
112 private:
113   vector<Incremental> pending_auth;
114   version_t last_rotating_ver;
115   uint64_t max_global_id;
116   uint64_t last_allocated_id;
117
118   void upgrade_format() override;
119
120   void export_keyring(KeyRing& keyring);
121   int import_keyring(KeyRing& keyring);
122
123   void push_cephx_inc(KeyServerData::Incremental& auth_inc) {
124     Incremental inc;
125     inc.inc_type = AUTH_DATA;
126     ::encode(auth_inc, inc.auth_data);
127     inc.auth_type = CEPH_AUTH_CEPHX;
128     pending_auth.push_back(inc);
129   }
130
131   /* validate mon caps ; don't care about caps for other services as
132    * we don't know how to validate them */
133   bool valid_caps(const vector<string>& caps, ostream *out) {
134     for (vector<string>::const_iterator p = caps.begin();
135          p != caps.end(); p += 2) {
136       if (!p->empty() && *p != "mon")
137         continue;
138       MonCap tmp;
139       if (!tmp.parse(*(p+1), out))
140         return false;
141     }
142     return true;
143   }
144
145   void on_active() override;
146   bool should_propose(double& delay) override;
147   void create_initial() override;
148   void update_from_paxos(bool *need_bootstrap) override;
149   void create_pending() override;  // prepare a new pending
150   bool prepare_global_id(MonOpRequestRef op);
151   void increase_max_global_id();
152   uint64_t assign_global_id(MonOpRequestRef op, bool should_increase_max);
153   // propose pending update to peers
154   void encode_pending(MonitorDBStore::TransactionRef t) override;
155   void encode_full(MonitorDBStore::TransactionRef t) override;
156   version_t get_trim_to() override;
157
158   bool preprocess_query(MonOpRequestRef op) override;  // true if processed.
159   bool prepare_update(MonOpRequestRef op) override;
160
161   bool prep_auth(MonOpRequestRef op, bool paxos_writable);
162
163   bool preprocess_command(MonOpRequestRef op);
164   bool prepare_command(MonOpRequestRef op);
165
166   bool check_rotate();
167
168   bool entity_is_pending(EntityName& entity);
169   int exists_and_matches_entity(
170       const auth_entity_t& entity,
171       bool has_secret,
172       stringstream& ss);
173   int exists_and_matches_entity(
174       const EntityName& name,
175       const EntityAuth& auth,
176       const map<string,bufferlist>& caps,
177       bool has_secret,
178       stringstream& ss);
179   int remove_entity(const EntityName &entity);
180   int add_entity(
181       const EntityName& name,
182       const EntityAuth& auth);
183
184  public:
185   AuthMonitor(Monitor *mn, Paxos *p, const string& service_name)
186     : PaxosService(mn, p, service_name),
187       last_rotating_ver(0),
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       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 string& cephx_secret,
214       const string& lockbox_secret,
215       auth_entity_t& cephx_entity,
216       auth_entity_t& lockbox_entity,
217       stringstream& ss);
218
219   void dump_info(Formatter *f);
220
221   bool is_valid_cephx_key(const 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 (buffer::error& e) { /* fallthrough */ }
230     return false;
231   }
232 };
233
234
235 WRITE_CLASS_ENCODER_FEATURES(AuthMonitor::Incremental)
236
237 #endif