Reindent server/core/adminusers.c

This commit is contained in:
Johan Wikman
2015-11-30 10:38:21 +02:00
parent 6f737d9484
commit f6e8662933
2 changed files with 264 additions and 233 deletions

View File

@ -37,24 +37,24 @@
* @verbatim * @verbatim
* Revision History * Revision History
* *
* Date Who Description * Date Who Description
* 18/07/13 Mark Riddoch Initial implementation * 18/07/13 Mark Riddoch Initial implementation
* 23/07/13 Mark Riddoch Addition of error mechanism to add user * 23/07/13 Mark Riddoch Addition of error mechanism to add user
* *
* @endverbatim * @endverbatim
*/ */
static USERS *loadUsers(); static USERS *loadUsers();
static void initialise(); static void initialise();
static USERS *users = NULL; static USERS *users = NULL;
static int admin_init = 0; static int admin_init = 0;
static char *ADMIN_ERR_NOMEM = "Out of memory"; static char *ADMIN_ERR_NOMEM = "Out of memory";
static char *ADMIN_ERR_FILEOPEN = "Unable to create password file"; static char *ADMIN_ERR_FILEOPEN = "Unable to create password file";
static char *ADMIN_ERR_DUPLICATE = "Duplicate username specified"; static char *ADMIN_ERR_DUPLICATE = "Duplicate username specified";
static char *ADMIN_ERR_USERNOTFOUND = "User not found"; static char *ADMIN_ERR_USERNOTFOUND = "User not found";
static char *ADMIN_ERR_AUTHENTICATION = "Authentication failed"; static char *ADMIN_ERR_AUTHENTICATION = "Authentication failed";
static char *ADMIN_ERR_FILEAPPEND = "Unable to append to password file"; static char *ADMIN_ERR_FILEAPPEND = "Unable to append to password file";
static char *ADMIN_ERR_PWDFILEOPEN = "Failed to open password file"; static char *ADMIN_ERR_PWDFILEOPEN = "Failed to open password file";
static char *ADMIN_ERR_TMPFILEOPEN = "Failed to open temporary password file"; static char *ADMIN_ERR_TMPFILEOPEN = "Failed to open temporary password file";
static char *ADMIN_ERR_PWDFILEACCESS = "Failed to access password file"; static char *ADMIN_ERR_PWDFILEACCESS = "Failed to access password file";
@ -69,38 +69,47 @@ static const int LINELEN=80;
static void static void
initialise() initialise()
{ {
if (admin_init) if (admin_init)
return; {
admin_init = 1; return;
users = loadUsers(); }
admin_init = 1;
users = loadUsers();
} }
/** /**
* Verify a username and password * Verify a username and password
* *
* @param username Username to verify * @param username Username to verify
* @param password Password to verify * @param password Password to verify
* @return Non-zero if the username/password combination is valid * @return Non-zero if the username/password combination is valid
*/ */
int int
admin_verify(char *username, char *password) admin_verify(char *username, char *password)
{ {
char *pw; char *pw;
initialise(); initialise();
if (users == NULL) if (users == NULL)
{ {
if (strcmp(username, "admin") == 0 && strcmp(password, "mariadb") == 0) if (strcmp(username, "admin") == 0 && strcmp(password, "mariadb") == 0)
return 1; {
} return 1;
else }
{ }
if ((pw = users_fetch(users, username)) == NULL) else
return 0; {
if (strcmp(pw, crypt(password, ADMIN_SALT)) == 0) if ((pw = users_fetch(users, username)) == NULL)
return 1; {
} return 0;
return 0; }
if (strcmp(pw, crypt(password, ADMIN_SALT)) == 0)
{
return 1;
}
}
return 0;
} }
@ -109,223 +118,239 @@ char *pw;
* *
* @return Table of users * @return Table of users
*/ */
static USERS * static USERS *
loadUsers() loadUsers()
{ {
USERS *rval; USERS *rval;
FILE *fp; FILE *fp;
char fname[1024], *home; char fname[1024], *home;
char uname[80], passwd[80]; char uname[80], passwd[80];
initialise(); initialise();
snprintf(fname,1023, "%s/passwd", get_datadir()); snprintf(fname,1023, "%s/passwd", get_datadir());
fname[1023] = '\0'; fname[1023] = '\0';
if ((fp = fopen(fname, "r")) == NULL) if ((fp = fopen(fname, "r")) == NULL)
return NULL; {
if ((rval = users_alloc()) == NULL) return NULL;
{ }
fclose(fp); if ((rval = users_alloc()) == NULL)
return NULL; {
} fclose(fp);
while (fscanf(fp, "%[^:]:%s\n", uname, passwd) == 2) return NULL;
{ }
users_add(rval, uname, passwd); while (fscanf(fp, "%[^:]:%s\n", uname, passwd) == 2)
} {
fclose(fp); users_add(rval, uname, passwd);
}
fclose(fp);
return rval; return rval;
} }
/** /**
* Add user * Add user
* *
* @param uname Name of the new user * @param uname Name of the new user
* @param passwd Password for the new user * @param passwd Password for the new user
* @return NULL on success or an error string on failure * @return NULL on success or an error string on failure
*/ */
char * char *
admin_add_user(char *uname, char *passwd) admin_add_user(char *uname, char *passwd)
{ {
FILE *fp; FILE *fp;
char fname[1024], *home, *cpasswd; char fname[1024], *home, *cpasswd;
initialise(); initialise();
if(access(get_datadir(), F_OK) != 0) if (access(get_datadir(), F_OK) != 0)
if(mkdir(get_datadir(), S_IRWXU) != 0 && errno != EEXIST) {
return ADMIN_ERR_PWDFILEOPEN; if (mkdir(get_datadir(), S_IRWXU) != 0 && errno != EEXIST)
{
return ADMIN_ERR_PWDFILEOPEN;
}
}
snprintf(fname,1023, "%s/passwd", get_datadir()); snprintf(fname,1023, "%s/passwd", get_datadir());
fname[1023] = '\0'; fname[1023] = '\0';
if (users == NULL) if (users == NULL)
{ {
MXS_NOTICE("Create initial password file."); MXS_NOTICE("Create initial password file.");
if ((users = users_alloc()) == NULL) if ((users = users_alloc()) == NULL)
return ADMIN_ERR_NOMEM; {
if ((fp = fopen(fname, "w")) == NULL) return ADMIN_ERR_NOMEM;
{ }
MXS_ERROR("Unable to create password file %s.", fname); if ((fp = fopen(fname, "w")) == NULL)
return ADMIN_ERR_PWDFILEOPEN; {
} MXS_ERROR("Unable to create password file %s.", fname);
fclose(fp); return ADMIN_ERR_PWDFILEOPEN;
} }
if (users_fetch(users, uname) != NULL) fclose(fp);
{ }
return ADMIN_ERR_DUPLICATE; if (users_fetch(users, uname) != NULL)
} {
cpasswd = crypt(passwd, ADMIN_SALT); return ADMIN_ERR_DUPLICATE;
users_add(users, uname, cpasswd); }
if ((fp = fopen(fname, "a")) == NULL) cpasswd = crypt(passwd, ADMIN_SALT);
{ users_add(users, uname, cpasswd);
MXS_ERROR("Unable to append to password file %s.", fname); if ((fp = fopen(fname, "a")) == NULL)
return ADMIN_ERR_FILEAPPEND; {
} MXS_ERROR("Unable to append to password file %s.", fname);
fprintf(fp, "%s:%s\n", uname, cpasswd); return ADMIN_ERR_FILEAPPEND;
fclose(fp); }
return ADMIN_SUCCESS; fprintf(fp, "%s:%s\n", uname, cpasswd);
fclose(fp);
return ADMIN_SUCCESS;
} }
/** /**
* Remove maxscale user from in-memory structure and from password file * Remove maxscale user from in-memory structure and from password file
* *
* @param uname Name of the new user * @param uname Name of the new user
* @param passwd Password for the new user * @param passwd Password for the new user
* @return NULL on success or an error string on failure * @return NULL on success or an error string on failure
*/ */
char* admin_remove_user( char* admin_remove_user(
char* uname, char* uname,
char* passwd) char* passwd)
{ {
FILE* fp; FILE* fp;
FILE* fp_tmp; FILE* fp_tmp;
char fname[1024]; char fname[1024];
char fname_tmp[1024]; char fname_tmp[1024];
char* home; char* home;
char fusr[LINELEN]; char fusr[LINELEN];
char fpwd[LINELEN]; char fpwd[LINELEN];
char line[LINELEN]; char line[LINELEN];
fpos_t rpos; fpos_t rpos;
int n_deleted; int n_deleted;
if (!admin_search_user(uname)) { if (!admin_search_user(uname))
MXS_ERROR("Couldn't find user %s. Removing user failed.", uname); {
return ADMIN_ERR_USERNOTFOUND; MXS_ERROR("Couldn't find user %s. Removing user failed.", uname);
} return ADMIN_ERR_USERNOTFOUND;
}
if (admin_verify(uname, passwd) == 0) {
MXS_ERROR("Authentication failed, wrong user/password " if (admin_verify(uname, passwd) == 0)
"combination. Removing user failed."); {
return ADMIN_ERR_AUTHENTICATION; MXS_ERROR("Authentication failed, wrong user/password "
} "combination. Removing user failed.");
return ADMIN_ERR_AUTHENTICATION;
}
/** Remove user from in-memory structure */ /** Remove user from in-memory structure */
n_deleted = users_delete(users, uname); n_deleted = users_delete(users, uname);
if (n_deleted == 0) { if (n_deleted == 0)
MXS_ERROR("Deleting the only user is forbidden. Add new " {
"user before deleting the one."); MXS_ERROR("Deleting the only user is forbidden. Add new "
return ADMIN_ERR_DELLASTUSER; "user before deleting the one.");
} return ADMIN_ERR_DELLASTUSER;
/** }
* Open passwd file and remove user from the file. /**
*/ * Open passwd file and remove user from the file.
snprintf(fname,1023, "%s/passwd", get_datadir()); */
snprintf(fname_tmp,1023, "%s/passwd_tmp", get_datadir()); snprintf(fname, 1023, "%s/passwd", get_datadir());
fname[1023] = '\0'; snprintf(fname_tmp, 1023, "%s/passwd_tmp", get_datadir());
fname_tmp[1023] = '\0'; fname[1023] = '\0';
/** fname_tmp[1023] = '\0';
* Rewrite passwd file from memory. /**
*/ * Rewrite passwd file from memory.
if ((fp = fopen(fname, "r")) == NULL) */
{ if ((fp = fopen(fname, "r")) == NULL)
int err = errno; {
MXS_ERROR("Unable to open password file %s : errno %d.\n" int err = errno;
"Removing user from file failed; it must be done " MXS_ERROR("Unable to open password file %s : errno %d.\n"
"manually.", "Removing user from file failed; it must be done "
fname, "manually.",
err); fname,
return ADMIN_ERR_PWDFILEOPEN; err);
} return ADMIN_ERR_PWDFILEOPEN;
/** }
* Open temporary passwd file. /**
*/ * Open temporary passwd file.
if ((fp_tmp = fopen(fname_tmp, "w")) == NULL) */
{ if ((fp_tmp = fopen(fname_tmp, "w")) == NULL)
int err = errno; {
MXS_ERROR("Unable to open tmp file %s : errno %d.\n" int err = errno;
"Removing user from passwd file failed; it must be done " MXS_ERROR("Unable to open tmp file %s : errno %d.\n"
"manually.", "Removing user from passwd file failed; it must be done "
fname_tmp, "manually.",
err); fname_tmp,
fclose(fp); err);
return ADMIN_ERR_TMPFILEOPEN; fclose(fp);
} return ADMIN_ERR_TMPFILEOPEN;
}
/**
* Scan passwd and copy all but matching lines to temp file. /**
*/ * Scan passwd and copy all but matching lines to temp file.
if (fgetpos(fp, &rpos) != 0) { */
int err = errno; if (fgetpos(fp, &rpos) != 0)
MXS_ERROR("Unable to process passwd file %s : errno %d.\n" {
"Removing user from file failed, and must be done " int err = errno;
"manually.", MXS_ERROR("Unable to process passwd file %s : errno %d.\n"
fname, "Removing user from file failed, and must be done "
err); "manually.",
fclose(fp); fname,
fclose(fp_tmp); err);
unlink(fname_tmp);
return ADMIN_ERR_PWDFILEACCESS;
}
while (fscanf(fp, "%[^:]:%s\n", fusr, fpwd) == 2)
{
/**
* Compare username what was found from passwd file.
* Unmatching lines are copied to tmp file.
*/
if (strncmp(uname, fusr, strlen(uname)+1) != 0) {
if(fsetpos(fp, &rpos) != 0){ /** one step back */
MXS_ERROR("Unable to set stream position. ");
}
fgets(line, LINELEN, fp);
fputs(line, fp_tmp);
}
if (fgetpos(fp, &rpos) != 0) {
int err = errno;
MXS_ERROR("Unable to process passwd file %s : "
"errno %d.\n"
"Removing user from file failed, and must be "
"done manually.",
fname,
err);
fclose(fp);
fclose(fp_tmp);
unlink(fname_tmp);
return ADMIN_ERR_PWDFILEACCESS;
}
}
fclose(fp); fclose(fp);
/**
* Replace original passwd file with new.
*/
if (rename(fname_tmp, fname)) {
int err = errno;
MXS_ERROR("Unable to rename new passwd file %s : errno "
"%d.\n"
"Rename it to %s manually.",
fname_tmp,
err,
fname);
unlink(fname_tmp);
fclose(fp_tmp);
return ADMIN_ERR_PWDFILEACCESS;
}
fclose(fp_tmp); fclose(fp_tmp);
return ADMIN_SUCCESS; unlink(fname_tmp);
return ADMIN_ERR_PWDFILEACCESS;
}
while (fscanf(fp, "%[^:]:%s\n", fusr, fpwd) == 2)
{
/**
* Compare username what was found from passwd file.
* Unmatching lines are copied to tmp file.
*/
if (strncmp(uname, fusr, strlen(uname)+1) != 0)
{
if(fsetpos(fp, &rpos) != 0)
{ /** one step back */
MXS_ERROR("Unable to set stream position. ");
}
fgets(line, LINELEN, fp);
fputs(line, fp_tmp);
}
if (fgetpos(fp, &rpos) != 0)
{
int err = errno;
MXS_ERROR("Unable to process passwd file %s : "
"errno %d.\n"
"Removing user from file failed, and must be "
"done manually.",
fname,
err);
fclose(fp);
fclose(fp_tmp);
unlink(fname_tmp);
return ADMIN_ERR_PWDFILEACCESS;
}
}
fclose(fp);
/**
* Replace original passwd file with new.
*/
if (rename(fname_tmp, fname))
{
int err = errno;
MXS_ERROR("Unable to rename new passwd file %s : errno "
"%d.\n"
"Rename it to %s manually.",
fname_tmp,
err,
fname);
unlink(fname_tmp);
fclose(fp_tmp);
return ADMIN_ERR_PWDFILEACCESS;
}
fclose(fp_tmp);
return ADMIN_SUCCESS;
} }
@ -333,28 +358,34 @@ char* admin_remove_user(
/** /**
* Check for existance of the user * Check for existance of the user
* *
* @param user The user name to test * @param user The user name to test
* @return Non-zero if the user exists * @return Non-zero if the user exists
*/ */
int int
admin_search_user(char *user) admin_search_user(char *user)
{ {
initialise(); initialise();
if (users == NULL) if (users == NULL)
return 0; {
return users_fetch(users, user) != NULL; return 0;
}
return users_fetch(users, user) != NULL;
} }
/** /**
* Print the statistics and user names of the administration users * Print the statistics and user names of the administration users
* *
* @param dcb A DCB to send the output to * @param dcb A DCB to send the output to
*/ */
void void
dcb_PrintAdminUsers(DCB *dcb) dcb_PrintAdminUsers(DCB *dcb)
{ {
if (users) if (users)
dcb_usersPrint(dcb, users); {
else dcb_usersPrint(dcb, users);
dcb_printf(dcb, "No administration users have been defined.\n"); }
else
{
dcb_printf(dcb, "No administration users have been defined.\n");
}
} }

View File

@ -24,19 +24,19 @@
* @verbatim * @verbatim
* Revision History * Revision History
* *
* Date Who Description * Date Who Description
* 18/07/13 Mark Riddoch Initial implementation * 18/07/13 Mark Riddoch Initial implementation
* *
* @endverbatim * @endverbatim
*/ */
#include <dcb.h> #include <dcb.h>
#define ADMIN_SALT "MS" #define ADMIN_SALT "MS"
extern int admin_verify(char *, char *); extern int admin_verify(char *, char *);
extern char *admin_add_user(char *, char *); extern char *admin_add_user(char *, char *);
extern int admin_search_user(char *); extern int admin_search_user(char *);
extern void dcb_PrintAdminUsers(DCB *dcb); extern void dcb_PrintAdminUsers(DCB *dcb);
char* admin_remove_user(char* uname, char* passwd); char* admin_remove_user(char* uname, char* passwd);