~ubuntu-branches/ubuntu/vivid/drizzle/vivid-proposed

« back to all changes in this revision

Viewing changes to plugin/auth_file/auth_file.cc

  • Committer: Package Import Robot
  • Author(s): Tobias Frost
  • Date: 2013-08-22 20:18:31 UTC
  • mto: (20.1.1 sid)
  • mto: This revision was merged to the branch mainline in revision 21.
  • Revision ID: package-import@ubuntu.com-20130822201831-gn3ozsh7o7wmc5tk
Tags: upstream-7.2.3
ImportĀ upstreamĀ versionĀ 7.2.3

Show diffs side-by-side

added added

removed removed

Lines of Context:
27
27
#include <boost/program_options.hpp>
28
28
#include <boost/filesystem.hpp>
29
29
 
 
30
#include <drizzled/item.h>
30
31
#include <drizzled/configmake.h>
31
32
#include <drizzled/plugin/authentication.h>
32
33
#include <drizzled/identifier.h>
43
44
namespace auth_file {
44
45
 
45
46
static const fs::path DEFAULT_USERS_FILE= SYSCONFDIR "/drizzle.users";
 
47
typedef std::map<string, string> users_t;
 
48
bool updateUsersFile(Session *, set_var *);
 
49
bool parseUsersFile(std::string, users_t&);
46
50
 
47
51
class AuthFile : public plugin::Authentication
48
52
{
49
53
public:
50
 
  AuthFile(fs::path users_file_arg);
 
54
  AuthFile(std::string users_file_arg);
51
55
 
52
56
  /**
53
57
   * Retrieve the last error encountered in the class.
54
58
   */
55
59
  const string& getError() const;
56
60
 
57
 
  /**
58
 
   * Load the users file into a map cache.
59
 
   *
60
 
   * @return True on success, false on error. If false is returned an error
61
 
   *  is set and can be retrieved with getError().
62
 
   */
63
 
  bool loadFile();
 
61
  std::string& getUsersFile();
 
62
  bool setUsersFile(std::string& usersFile);
64
63
 
65
64
private:
66
65
 
85
84
                       const string &scrambled_password);
86
85
 
87
86
  string error;
88
 
  const fs::path users_file;
 
87
  fs::path users_file;
 
88
  std::string sysvar_users_file;
89
89
 
90
90
  /**
91
91
   * Cache or username:password entries from the file.
92
92
   */
93
 
  typedef std::map<string, string> users_t;
94
93
  users_t users;
 
94
  /**
 
95
   * This method is called to update the users cache with the new 
 
96
   * username:password pairs given in new users file upon update.
 
97
   */
 
98
  void setUsers(users_t);
 
99
  /**
 
100
   * This method is called to delete all the cached username:password pairs
 
101
   * when users file is updated.
 
102
   */
 
103
  void clearUsers();
95
104
};
 
105
AuthFile *auth_file= NULL;
96
106
 
97
 
AuthFile::AuthFile(fs::path users_file_arg) :
 
107
AuthFile::AuthFile(std::string users_file_arg) :
98
108
  plugin::Authentication("auth_file"),
99
 
  users_file(users_file_arg)
 
109
  users_file(users_file_arg), sysvar_users_file(users_file_arg)
100
110
{
101
111
}
102
112
 
105
115
  return error;
106
116
}
107
117
 
108
 
bool AuthFile::loadFile()
109
 
{
110
 
  ifstream file(users_file.string().c_str());
111
 
 
112
 
  if (!file.is_open())
113
 
  {
114
 
    error = "Could not open users file: " + users_file.string();
115
 
    return false;
116
 
  }
117
 
 
118
 
  string line;
119
 
  while (getline(file, line))
120
 
  {
121
 
    /* Ignore blank lines and lines starting with '#'. */
122
 
    if (line.empty() || line[line.find_first_not_of(" \t")] == '#')
123
 
      continue;
124
 
 
125
 
    string username;
126
 
    string password;
127
 
    size_t password_offset = line.find(":");
128
 
    if (password_offset == string::npos)
129
 
      username = line;
130
 
    else
131
 
    {
132
 
      username = string(line, 0, password_offset);
133
 
      password = string(line, password_offset + 1);
134
 
    }
135
 
 
136
 
    if (not users.insert(pair<string, string>(username, password)).second)
137
 
    {
138
 
      error = "Duplicate entry found in users file: " + username;
139
 
      return false;
140
 
    }
141
 
  }
142
 
  return true;
 
118
std::string& AuthFile::getUsersFile()
 
119
{
 
120
  return sysvar_users_file;
 
121
}
 
122
 
 
123
bool AuthFile::setUsersFile(std::string& usersFile)
 
124
{
 
125
  if (usersFile.empty())
 
126
  {
 
127
    errmsg_printf(error::ERROR, _("users file cannot be an empty string"));
 
128
    return false;  // error
 
129
  }
 
130
  users_t users_dummy;
 
131
  if(parseUsersFile(usersFile, users_dummy))
 
132
  {
 
133
    this->clearUsers();
 
134
    this->setUsers(users_dummy);
 
135
    sysvar_users_file= usersFile;
 
136
    fs::path newUsersFile(getUsersFile());
 
137
    users_file= newUsersFile;
 
138
    return true;  //success
 
139
  }
 
140
  return false;  // error
143
141
}
144
142
 
145
143
bool AuthFile::verifyMySQLHash(const string &password,
195
193
    : password == *user;
196
194
}
197
195
 
 
196
void AuthFile::setUsers(users_t users_dummy)
 
197
{
 
198
  users.insert(users_dummy.begin(), users_dummy.end());
 
199
}
 
200
 
 
201
void AuthFile::clearUsers()
 
202
{
 
203
  users.clear();
 
204
}
 
205
 
 
206
/**
 
207
 * This function is called when the value of users file is changed in the system.
 
208
 *
 
209
 * @return False on success, True on error.
 
210
 */
 
211
bool updateUsersFile(Session *, set_var* var)
 
212
{
 
213
  if (not var->value->str_value.empty())
 
214
  {
 
215
    std::string newUsersFile(var->value->str_value.data());
 
216
    if (auth_file->setUsersFile(newUsersFile))
 
217
      return false; //success
 
218
    else
 
219
      return true; // error
 
220
  }
 
221
  errmsg_printf(error::ERROR, _("auth_file file cannot be NULL"));
 
222
  return true; // error
 
223
}
 
224
 
 
225
/**
 
226
 * Parse the users file into a map cache.
 
227
 *
 
228
 * @return True on success, false on error. If an error is encountered, false is
 
229
 * returned with error message printed.
 
230
 */
 
231
bool parseUsersFile(std::string new_users_file, users_t& users_dummy)
 
232
{
 
233
  ifstream file(new_users_file.c_str());
 
234
 
 
235
  if (!file.is_open())
 
236
  {
 
237
    string error_msg= "Could not open users file: " + new_users_file;
 
238
    errmsg_printf(error::ERROR, _(error_msg.c_str()));
 
239
    return false;
 
240
  }
 
241
 
 
242
  string line;
 
243
  try
 
244
  {
 
245
    while (getline(file, line))
 
246
    {
 
247
      /* Ignore blank lines and lines starting with '#'. */
 
248
      if (line.empty() || line[line.find_first_not_of(" \t")] == '#')
 
249
        continue;
 
250
 
 
251
      string username;
 
252
      string password;
 
253
      size_t password_offset = line.find(":");
 
254
      if (password_offset == string::npos)
 
255
        username = line;
 
256
      else
 
257
      {
 
258
        username = string(line, 0, password_offset);
 
259
        password = string(line, password_offset + 1);
 
260
      }
 
261
  
 
262
      if (not users_dummy.insert(pair<string, string>(username, password)).second)
 
263
      {
 
264
        string error_msg= "Duplicate entry found in users file: " + username;
 
265
        errmsg_printf(error::ERROR, _(error_msg.c_str()));
 
266
        return false;
 
267
      }
 
268
    }
 
269
    return true;
 
270
  }
 
271
  catch (const std::exception &e)
 
272
  {
 
273
    /* On any non-EOF break, unparseable line */
 
274
    string error_msg= "Unable to parse users file " + new_users_file + ":" + e.what();
 
275
    errmsg_printf(error::ERROR, _(error_msg.c_str()));
 
276
    return false;
 
277
  }
 
278
}
 
279
 
198
280
static int init(module::Context &context)
199
281
{
200
282
  const module::option_map &vm= context.getOptions();
201
283
 
202
 
  AuthFile *auth_file = new AuthFile(fs::path(vm["users"].as<string>()));
203
 
  if (not auth_file->loadFile())
 
284
  auth_file= new AuthFile(vm["users"].as<string>());
 
285
  if (!auth_file->setUsersFile(auth_file->getUsersFile()))
204
286
  {
205
287
    errmsg_printf(error::ERROR, _("Could not load auth file: %s\n"), auth_file->getError().c_str());
206
288
    delete auth_file;
208
290
  }
209
291
 
210
292
  context.add(auth_file);
211
 
  context.registerVariable(new sys_var_const_string_val("users", vm["users"].as<string>()));
 
293
  context.registerVariable(new sys_var_std_string("users", auth_file->getUsersFile(), NULL, &updateUsersFile));
212
294
 
213
295
  return 0;
214
296
}