~drizzle-trunk/drizzle/development

1317.1.5 by Monty Taylor
Added Authorization interface.
1
/* -*- mode: c++; c-basic-offset: 2; indent-tabs-mode: nil; -*-
2
 *  vim:expandtab:shiftwidth=2:tabstop=2:smarttab:
3
 *
4
 *  Copyright (C) 2010 Monty Taylor
5
 *
6
 *  This program is free software; you can redistribute it and/or modify
7
 *  it under the terms of the GNU General Public License as published by
8
 *  the Free Software Foundation; either version 2 of the License, or
9
 *  (at your option) any later version.
10
 *
11
 *  This program is distributed in the hope that it will be useful,
12
 *  but WITHOUT ANY WARRANTY; without even the implied warranty of
13
 *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
14
 *  GNU General Public License for more details.
15
 *
16
 *  You should have received a copy of the GNU General Public License
17
 *  along with this program; if not, write to the Free Software
18
 *  Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA
19
 */
20
21
#include "config.h"
22
23
#include <vector>
24
25
#include "drizzled/plugin/authorization.h"
26
#include "drizzled/security_context.h"
1471.2.2 by Monty Taylor
Updated Authorization plugin interface to use new Schema|TableIdentifier
27
#include "drizzled/table_identifier.h"
1317.1.5 by Monty Taylor
Added Authorization interface.
28
#include "drizzled/error.h"
29
#include "drizzled/session.h"
30
#include "drizzled/plugin/registry.h"
31
#include "drizzled/gettext.h"
32
33
using namespace std;
34
35
namespace drizzled
36
{
37
38
vector<plugin::Authorization *> authorization_plugins;
39
40
41
bool plugin::Authorization::addPlugin(plugin::Authorization *auth)
42
{
43
  if (auth != NULL)
44
    authorization_plugins.push_back(auth);
45
  return false;
46
}
47
48
void plugin::Authorization::removePlugin(plugin::Authorization *auth)
49
{
50
  if (auth != NULL)
51
  {
52
    authorization_plugins.erase(find(authorization_plugins.begin(),
53
                                     authorization_plugins.end(),
54
                                     auth));
55
  }
56
}
57
58
namespace
59
{
60
61
class RestrictDbFunctor :
62
  public unary_function<plugin::Authorization *, bool>
63
{
64
  const SecurityContext &user_ctx;
1471.2.2 by Monty Taylor
Updated Authorization plugin interface to use new Schema|TableIdentifier
65
  SchemaIdentifier &schema;
1317.1.5 by Monty Taylor
Added Authorization interface.
66
public:
67
  RestrictDbFunctor(const SecurityContext &user_ctx_arg,
1471.2.2 by Monty Taylor
Updated Authorization plugin interface to use new Schema|TableIdentifier
68
                    SchemaIdentifier &schema_arg) :
1317.1.5 by Monty Taylor
Added Authorization interface.
69
    unary_function<plugin::Authorization *, bool>(),
70
    user_ctx(user_ctx_arg),
71
    schema(schema_arg)
72
  { }
73
74
  inline result_type operator()(argument_type auth)
75
  {
76
    return auth->restrictSchema(user_ctx, schema);
77
  }
78
};
79
80
class RestrictTableFunctor :
81
  public unary_function<plugin::Authorization *, bool>
82
{
83
  const SecurityContext &user_ctx;
1471.2.2 by Monty Taylor
Updated Authorization plugin interface to use new Schema|TableIdentifier
84
  TableIdentifier &table;
1317.1.5 by Monty Taylor
Added Authorization interface.
85
public:
86
  RestrictTableFunctor(const SecurityContext &user_ctx_arg,
1471.2.2 by Monty Taylor
Updated Authorization plugin interface to use new Schema|TableIdentifier
87
                       TableIdentifier &table_arg) :
1317.1.5 by Monty Taylor
Added Authorization interface.
88
    unary_function<plugin::Authorization *, bool>(),
89
    user_ctx(user_ctx_arg),
90
    table(table_arg)
91
  { }
92
93
  inline result_type operator()(argument_type auth)
94
  {
1471.2.2 by Monty Taylor
Updated Authorization plugin interface to use new Schema|TableIdentifier
95
    return auth->restrictTable(user_ctx, table);
1317.1.5 by Monty Taylor
Added Authorization interface.
96
  }
97
};
98
99
class RestrictProcessFunctor :
100
  public unary_function<plugin::Authorization *, bool>
101
{
102
  const SecurityContext &user_ctx;
103
  const SecurityContext &session_ctx;
104
public:
105
  RestrictProcessFunctor(const SecurityContext &user_ctx_arg,
106
                         const SecurityContext &session_ctx_arg) :
107
    unary_function<plugin::Authorization *, bool>(),
108
    user_ctx(user_ctx_arg),
109
    session_ctx(session_ctx_arg)
110
  { }
111
112
  inline result_type operator()(argument_type auth)
113
  {
114
    return auth->restrictProcess(user_ctx, session_ctx);
115
  }
116
};
117
1471.2.2 by Monty Taylor
Updated Authorization plugin interface to use new Schema|TableIdentifier
118
class PruneSchemaFunctor :
119
  public unary_function<SchemaIdentifier&, bool>
120
{
121
  const SecurityContext &user_ctx;
122
public:
123
  PruneSchemaFunctor(const SecurityContext &user_ctx_arg) :
124
    unary_function<SchemaIdentifier&, bool>(),
125
    user_ctx(user_ctx_arg)
126
  { }
127
128
  inline result_type operator()(argument_type auth)
129
  {
130
    return not plugin::Authorization::isAuthorized(user_ctx, auth, false);
131
  }
132
};
133
1317.1.5 by Monty Taylor
Added Authorization interface.
134
} /* namespace */
135
136
bool plugin::Authorization::isAuthorized(const SecurityContext &user_ctx,
1415 by Brian Aker
Mass overhaul to use schema_identifier.
137
                                         SchemaIdentifier &schema_identifier,
1317.1.5 by Monty Taylor
Added Authorization interface.
138
                                         bool send_error)
139
{
140
  /* If we never loaded any authorization plugins, just return true */
1317.3.1 by Monty Taylor
Replaced calls of size()==0 with empty().
141
  if (authorization_plugins.empty())
1317.1.5 by Monty Taylor
Added Authorization interface.
142
    return true;
143
144
  /* Use find_if instead of foreach so that we can collect return codes */
145
  vector<plugin::Authorization *>::const_iterator iter=
146
    find_if(authorization_plugins.begin(),
147
            authorization_plugins.end(),
1471.2.2 by Monty Taylor
Updated Authorization plugin interface to use new Schema|TableIdentifier
148
            RestrictDbFunctor(user_ctx, schema_identifier));
149
1317.1.5 by Monty Taylor
Added Authorization interface.
150
151
  /*
152
   * If iter is == end() here, that means that all of the plugins returned
153
   * false, which means that that each of them believe the user is authorized
154
   * to view the resource in question.
155
   */
156
  if (iter != authorization_plugins.end())
157
  {
158
    if (send_error)
159
    {
160
      my_error(ER_DBACCESS_DENIED_ERROR, MYF(0),
161
               user_ctx.getUser().c_str(),
162
               user_ctx.getIp().c_str(),
1415 by Brian Aker
Mass overhaul to use schema_identifier.
163
               schema_identifier.getSQLPath().c_str());
1317.1.5 by Monty Taylor
Added Authorization interface.
164
    }
165
    return false;
166
  }
167
  return true;
168
}
169
170
bool plugin::Authorization::isAuthorized(const SecurityContext &user_ctx,
1471.2.2 by Monty Taylor
Updated Authorization plugin interface to use new Schema|TableIdentifier
171
                                         TableIdentifier &table,
1317.1.5 by Monty Taylor
Added Authorization interface.
172
                                         bool send_error)
173
{
174
  /* If we never loaded any authorization plugins, just return true */
1317.3.1 by Monty Taylor
Replaced calls of size()==0 with empty().
175
  if (authorization_plugins.empty())
1317.1.5 by Monty Taylor
Added Authorization interface.
176
    return true;
177
178
  /* Use find_if instead of foreach so that we can collect return codes */
179
  vector<plugin::Authorization *>::const_iterator iter=
180
    find_if(authorization_plugins.begin(),
181
            authorization_plugins.end(),
1471.2.2 by Monty Taylor
Updated Authorization plugin interface to use new Schema|TableIdentifier
182
            RestrictTableFunctor(user_ctx, table));
1317.1.5 by Monty Taylor
Added Authorization interface.
183
184
  /*
185
   * If iter is == end() here, that means that all of the plugins returned
186
   * false, which means that that each of them believe the user is authorized
187
   * to view the resource in question.
188
   */
189
  if (iter != authorization_plugins.end())
190
  {
191
    if (send_error)
192
    {
193
      my_error(ER_DBACCESS_DENIED_ERROR, MYF(0),
194
               user_ctx.getUser().c_str(),
195
               user_ctx.getIp().c_str(),
1471.2.2 by Monty Taylor
Updated Authorization plugin interface to use new Schema|TableIdentifier
196
               table.getSQLPath().c_str());
1317.1.5 by Monty Taylor
Added Authorization interface.
197
    }
198
    return false;
199
  }
200
  return true;
201
}
202
203
bool plugin::Authorization::isAuthorized(const SecurityContext &user_ctx,
204
                                         const Session *session,
205
                                         bool send_error)
206
{
207
  const SecurityContext &session_ctx= session->getSecurityContext();
208
209
  /* If we never loaded any authorization plugins, just return true */
1317.3.1 by Monty Taylor
Replaced calls of size()==0 with empty().
210
  if (authorization_plugins.empty())
1317.1.5 by Monty Taylor
Added Authorization interface.
211
    return true;
212
213
  /* Use find_if instead of foreach so that we can collect return codes */
214
  vector<plugin::Authorization *>::const_iterator iter=
215
    find_if(authorization_plugins.begin(),
216
            authorization_plugins.end(),
217
            RestrictProcessFunctor(user_ctx, session_ctx));
218
219
  /*
220
   * If iter is == end() here, that means that all of the plugins returned
221
   * false, which means that that each of them believe the user is authorized
222
   * to view the resource in question.
223
   */
224
225
  if (iter != authorization_plugins.end())
226
  {
227
    if (send_error)
228
    {
229
      my_error(ER_KILL_DENIED_ERROR, MYF(0), session->thread_id);
230
    }
231
    return false;
232
  }
233
  return true;
234
}
235
236
void plugin::Authorization::pruneSchemaNames(const SecurityContext &user_ctx,
1415 by Brian Aker
Mass overhaul to use schema_identifier.
237
                                             SchemaIdentifierList &set_of_schemas)
1317.1.5 by Monty Taylor
Added Authorization interface.
238
{
239
  /* If we never loaded any authorization plugins, just return true */
1317.3.1 by Monty Taylor
Replaced calls of size()==0 with empty().
240
  if (authorization_plugins.empty())
1317.1.5 by Monty Taylor
Added Authorization interface.
241
    return;
242
1471.2.2 by Monty Taylor
Updated Authorization plugin interface to use new Schema|TableIdentifier
243
  set_of_schemas.erase(remove_if(set_of_schemas.begin(),
244
                                 set_of_schemas.end(),
245
                                 PruneSchemaFunctor(user_ctx)),
246
                       set_of_schemas.end());
1317.1.5 by Monty Taylor
Added Authorization interface.
247
}
248
249
} /* namespace drizzled */