Added 'remove user' to client API. New functions are

debugcmd.c : telnetdRemoveUser
adminusers.c : admin_remove_user

Also renamed admin_test_user to admin_search_user .
This commit is contained in:
vraatikka 2013-08-02 23:03:43 +03:00
parent 3357748aad
commit ca3638ae2c
3 changed files with 206 additions and 6 deletions

View File

@ -18,6 +18,7 @@
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <errno.h>
#define _XOPEN_SOURCE
#include <unistd.h>
#include <crypt.h>
@ -48,7 +49,15 @@ static int admin_init = 0;
static char *ADMIN_ERR_NOMEM = "Out of memory";
static char *ADMIN_ERR_FILEOPEN = "Unable to create password file";
static char *ADMIN_ERR_DUPLICATE = "Duplicate username specified";
static char *ADMIN_ERR_USERNOTFOUND = "User not found";
static char *ADMIN_ERR_AUTHENTICATION = "Authentication failed";
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_TMPFILEOPEN = "Failed to open temporary password file";
static char *ADMIN_ERR_PWDFILEACCESS = "Failed to access password file";
static char *ADMIN_SUCCESS = NULL;
static const int LINELEN=80;
/**
* Admin Users initialisation
@ -150,7 +159,7 @@ char fname[1024], *home, *cpasswd;
skygw_log_write(NULL, LOGFILE_ERROR,
"Unable to create password file %s.\n",
fname);
return ADMIN_ERR_FILEOPEN;
return ADMIN_ERR_PWDFILEOPEN;
}
fclose(fp);
}
@ -169,9 +178,145 @@ char fname[1024], *home, *cpasswd;
}
fprintf(fp, "%s:%s\n", uname, cpasswd);
fclose(fp);
return NULL;
return ADMIN_SUCCESS;
}
/**
* Remove maxscale user from in-memory structure and from password file
*
* @param uname Name of the new user
* @param passwd Password for the new user
* @return NULL on success or an error string on failure
*/
char* admin_remove_user(
char* uname,
char* passwd)
{
FILE* fp;
FILE* fp_tmp;
char fname[1024];
char fname_tmp[1024];
char* home;
char fusr[LINELEN];
char fpwd[LINELEN];
char line[LINELEN];
fpos_t rpos;
if (!admin_search_user(uname)) {
skygw_log_write(NULL,
LOGFILE_MESSAGE,
"Couldn't find user %s. Removing user failed", uname);
return ADMIN_ERR_USERNOTFOUND;
}
if (admin_verify(uname, passwd) == 0) {
skygw_log_write(NULL,
LOGFILE_MESSAGE,
"Authentication failed, wrong user/password combination.\n"
"Removing user failed");
return ADMIN_ERR_AUTHENTICATION;
}
/** Remove user from in-memory structure */
users_delete(users, uname);
/**
* Open passwd file and remove user from the file.
*/
if ((home = getenv("MAXSCALE_HOME")) != NULL) {
sprintf(fname, "%s/etc/passwd", home);
sprintf(fname_tmp, "%s/etc/passwd_tmp", home);
} else {
sprintf(fname, "/usr/local/skysql/MaxScale/etc/passwd");
sprintf(fname_tmp, "/usr/local/skysql/MaxScale/etc/passwd_tmp");
}
/**
* Rewrite passwd file from memory.
*/
if ((fp = fopen(fname, "r")) == NULL)
{
int err = errno;
skygw_log_write(NULL, LOGFILE_ERROR,
"Unable to open password file %s : errno %d.\n"
"Removing user from file failed; it must be done manually.",
fname,
err);
return ADMIN_ERR_PWDFILEOPEN;
}
/**
* Open temporary passwd file.
*/
if ((fp_tmp = fopen(fname_tmp, "w")) == NULL)
{
int err = errno;
skygw_log_write(NULL, LOGFILE_ERROR,
"Unable to open tmp file %s : errno %d.\n"
"Removing user from passwd file failed; "
"it must be done manually.",
fname_tmp,
err);
fclose(fp);
return ADMIN_ERR_TMPFILEOPEN;
}
/**
* Scan passwd and copy all but matching lines to temp file.
*/
if (fgetpos(fp, &rpos) != 0) {
int err = errno;
skygw_log_write(NULL, LOGFILE_ERROR,
"Unable to process passwd file %s : errno %d.\n"
"Removing user from file failed, and must be done manually.",
fname,
err);
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) {
fsetpos(fp, &rpos); /** one step back */
fgets(line, LINELEN, fp);
fputs(line, fp_tmp);
}
if (fgetpos(fp, &rpos) != 0) {
int err = errno;
skygw_log_write(NULL, LOGFILE_ERROR,
"Unable to process passwd file %s : errno %d.\n"
"Removing user from file failed, and must be "
"done manually.",
fname,
err);
return ADMIN_ERR_PWDFILEACCESS;
}
}
fclose(fp);
/**
* Replace original passwd file with new.
*/
if (rename(fname_tmp, fname)) {
int err = errno;
skygw_log_write(NULL, LOGFILE_ERROR,
"Unable to rename new passwd file %s : errno %d.\n"
"Rename it to %s manually.",
fname_tmp,
err,
fname);
return ADMIN_ERR_PWDFILEACCESS;
}
fclose(fp_tmp);
return ADMIN_SUCCESS;
}
/**
* Check for existance of the user
*
@ -179,7 +324,7 @@ char fname[1024], *home, *cpasswd;
* @return Non-zero if the user exists
*/
int
admin_test_user(char *user)
admin_search_user(char *user)
{
initialise();
if (users == NULL)

View File

@ -36,5 +36,7 @@ extern char *admin_add_user(char *, char *);
extern int admin_test_user(char *);
extern void dcb_PrintAdminUsers(DCB *dcb);
char* admin_remove_user(char* uname, char* passwd);
#endif

View File

@ -81,7 +81,7 @@ static void telnetdShowUsers(DCB *);
* The subcommands of the show command
*/
struct subcommand showoptions[] = {
{ "dcbs", 0, dprintAllDCBs, "Show all descriptor control blocks (network connections)",
{ "dcbs", 0, dprintAllDCBs, "Show all descriptor control blocks (network connections)",
{0, 0, 0} },
{ "dcb", 1, dprintDCB, "Show a single descriptor control block e.g. show dcb 0x493340",
{ARG_TYPE_ADDRESS, 0, 0} },
@ -191,6 +191,25 @@ struct subcommand addoptions[] = {
{0, 0, 0} }
};
static void telnetdRemoveUser(DCB *, char *, char *);
/**
* The subcommands of the remove command
*/
struct subcommand removeoptions[] = {
{
"user",
2,
telnetdRemoveUser,
"Remove existing maxscale user. Example : remove user john johnpwd",
{ARG_TYPE_STRING, ARG_TYPE_STRING, 0}
},
{
NULL, 0, NULL, NULL, {0, 0, 0}
}
};
/**
* The debug command table
*/
@ -200,6 +219,7 @@ static struct {
} cmds[] = {
{ "add", addoptions },
{ "clear", clearoptions },
{ "remove", removeoptions },
{ "restart", restartoptions },
{ "set", setoptions },
{ "show", showoptions },
@ -513,7 +533,7 @@ reload_config(DCB *dcb)
}
/**
* Add a new admin user
* Add a new maxscale admin user
*
* @param dcb The DCB for messages
* @param user The user name
@ -524,7 +544,7 @@ telnetdAddUser(DCB *dcb, char *user, char *passwd)
{
char *err;
if (admin_test_user(user))
if (admin_search_user(user))
{
dcb_printf(dcb, "User %s already exists.\n", user);
return;
@ -535,6 +555,39 @@ char *err;
dcb_printf(dcb, "Failed to add new user. %s\n", err);
}
/**
* Remove a maxscale admin user
*
* @param dcb The DCB for messages
* @param user The user name
* @param passwd The Password of the user
*/
static void telnetdRemoveUser(
DCB* dcb,
char* user,
char* passwd)
{
char* err;
if (!admin_search_user(user))
{
dcb_printf(dcb, "User %s doesn't exist.\n", user);
return;
}
if ((err = admin_remove_user(user, passwd)) == NULL)
{
dcb_printf(dcb, "User %s has been successfully removed.\n", user);
}
else
{
dcb_printf(dcb, "Failed to remove user %s. %s\n", user, err);
}
}
/**
* Print the adminsitration users
*