Browse Source

ckdb - allow disabling/enabling users

master
kanoi 10 years ago
parent
commit
27b722e66e
  1. 9
      src/ckdb.c
  2. 11
      src/ckdb.h
  3. 91
      src/ckdb_cmd.c
  4. 28
      src/ckdb_dbio.c

9
src/ckdb.c

@ -2052,6 +2052,7 @@ static void *socketer(__maybe_unused void *arg)
char *last_newid = NULL, *reply_newid = NULL; char *last_newid = NULL, *reply_newid = NULL;
char *last_setatts = NULL, *reply_setatts = NULL; char *last_setatts = NULL, *reply_setatts = NULL;
char *last_setopts = NULL, *reply_setopts = NULL; char *last_setopts = NULL, *reply_setopts = NULL;
char *last_userstatus = NULL, *reply_userstatus = NULL;
char *last_web = NULL, *reply_web = NULL; char *last_web = NULL, *reply_web = NULL;
char *reply_last, duptype[CMD_SIZ+1]; char *reply_last, duptype[CMD_SIZ+1];
enum cmd_values cmdnum; enum cmd_values cmdnum;
@ -2155,6 +2156,9 @@ static void *socketer(__maybe_unused void *arg)
} else if (last_setopts && strcmp(last_setopts, buf) == 0) { } else if (last_setopts && strcmp(last_setopts, buf) == 0) {
reply_last = reply_setopts; reply_last = reply_setopts;
dup = true; dup = true;
} else if (last_userstatus && strcmp(last_userstatus, buf) == 0) {
reply_last = reply_userstatus;
dup = true;
} else if (last_web && strcmp(last_web, buf) == 0) { } else if (last_web && strcmp(last_web, buf) == 0) {
reply_last = reply_web; reply_last = reply_web;
dup = true; dup = true;
@ -2255,6 +2259,7 @@ static void *socketer(__maybe_unused void *arg)
case CMD_BLOCKLIST: case CMD_BLOCKLIST:
case CMD_NEWID: case CMD_NEWID:
case CMD_STATS: case CMD_STATS:
case CMD_USERSTATUS:
ans = ckdb_cmds[which_cmds].func(NULL, cmd, id, &now, ans = ckdb_cmds[which_cmds].func(NULL, cmd, id, &now,
by_default, by_default,
(char *)__func__, (char *)__func__,
@ -2297,6 +2302,9 @@ static void *socketer(__maybe_unused void *arg)
case CMD_SETOPTS: case CMD_SETOPTS:
STORELASTREPLY(setopts); STORELASTREPLY(setopts);
break; break;
case CMD_USERSTATUS:
STORELASTREPLY(userstatus);
break;
// The rest // The rest
default: default:
free(rep); free(rep);
@ -2503,6 +2511,7 @@ static bool reload_line(PGconn *conn, char *filename, uint64_t count, char *buf)
case CMD_DSP: case CMD_DSP:
case CMD_STATS: case CMD_STATS:
case CMD_PPLNS: case CMD_PPLNS:
case CMD_USERSTATUS:
LOGERR("%s() Message line %"PRIu64" '%s' - invalid - ignored", LOGERR("%s() Message line %"PRIu64" '%s' - invalid - ignored",
__func__, count, cmd); __func__, count, cmd);
break; break;

11
src/ckdb.h

@ -52,7 +52,7 @@
#define DB_VLOCK "1" #define DB_VLOCK "1"
#define DB_VERSION "0.9.4" #define DB_VERSION "0.9.4"
#define CKDB_VERSION DB_VERSION"-0.642" #define CKDB_VERSION DB_VERSION"-0.643"
#define WHERE_FFL " - from %s %s() line %d" #define WHERE_FFL " - from %s %s() line %d"
#define WHERE_FFL_HERE __FILE__, __func__, __LINE__ #define WHERE_FFL_HERE __FILE__, __func__, __LINE__
@ -303,6 +303,7 @@ enum cmd_values {
CMD_DSP, CMD_DSP,
CMD_STATS, CMD_STATS,
CMD_PPLNS, CMD_PPLNS,
CMD_USERSTATUS,
CMD_END CMD_END
}; };
@ -641,7 +642,7 @@ typedef struct users {
int64_t userid; int64_t userid;
char username[TXT_BIG+1]; char username[TXT_BIG+1];
char usertrim[TXT_BIG+1]; // Non DB field char usertrim[TXT_BIG+1]; // Non DB field
// TODO: Anything in 'status' disables the account // Anything in 'status' fails mining authentication
char status[TXT_BIG+1]; char status[TXT_BIG+1];
char emailaddress[TXT_BIG+1]; char emailaddress[TXT_BIG+1];
tv_t joineddate; tv_t joineddate;
@ -1544,9 +1545,9 @@ extern char *pqerrmsg(PGconn *conn);
extern int64_t nextid(PGconn *conn, char *idname, int64_t increment, extern int64_t nextid(PGconn *conn, char *idname, int64_t increment,
tv_t *cd, char *by, char *code, char *inet); tv_t *cd, char *by, char *code, char *inet);
extern bool users_pass_email(PGconn *conn, K_ITEM *u_item, char *oldhash, extern bool users_update(PGconn *conn, K_ITEM *u_item, char *oldhash,
char *newhash, char *email, char *by, char *code, char *newhash, char *email, char *by, char *code,
char *inet, tv_t *cd, K_TREE *trf_root); char *inet, tv_t *cd, K_TREE *trf_root, char *status);
extern K_ITEM *users_add(PGconn *conn, char *username, char *emailaddress, extern K_ITEM *users_add(PGconn *conn, char *username, char *emailaddress,
char *passwordhash, char *by, char *code, char *inet, char *passwordhash, char *by, char *code, char *inet,
tv_t *cd, K_TREE *trf_root); tv_t *cd, K_TREE *trf_root);

91
src/ckdb_cmd.c

@ -97,12 +97,13 @@ static char *cmd_newpass(__maybe_unused PGconn *conn, char *cmd, char *id,
K_RUNLOCK(users_free); K_RUNLOCK(users_free);
if (u_item) { if (u_item) {
ok = users_pass_email(NULL, u_item, ok = users_update(NULL, u_item,
oldhash, oldhash,
transfer_data(i_newhash), transfer_data(i_newhash),
NULL, NULL,
by, code, inet, now, by, code, inet, now,
trf_root); trf_root,
NULL);
} else } else
ok = false; ok = false;
} }
@ -261,10 +262,12 @@ static char *cmd_userset(PGconn *conn, char *cmd, char *id,
} }
if (email && *email) { if (email && *email) {
ok = users_pass_email(conn, u_item, NULL, ok = users_update(conn, u_item,
NULL, email, NULL, NULL,
by, code, inet, email,
now, trf_root); by, code, inet, now,
trf_root,
NULL);
if (!ok) { if (!ok) {
reason = "email error"; reason = "email error";
goto struckout; goto struckout;
@ -3392,6 +3395,69 @@ static char *cmd_stats(__maybe_unused PGconn *conn, char *cmd, char *id,
return buf; return buf;
} }
// TODO: add to heartbeat to disable the miner if active and status != ""
static char *cmd_userstatus(PGconn *conn, char *cmd, char *id, tv_t *now, char *by,
char *code, char *inet, __maybe_unused tv_t *cd,
K_TREE *trf_root)
{
char reply[1024] = "";
size_t siz = sizeof(reply);
K_ITEM *i_username, *i_userid, *i_status, *u_item;
int64_t userid;
char *status;
USERS *users;
bool ok;
LOGDEBUG("%s(): cmd '%s'", __func__, cmd);
i_username = optional_name(trf_root, "username", 3, (char *)userpatt, reply, siz);
i_userid = optional_name(trf_root, "userid", 1, (char *)intpatt, reply, siz);
// Either username or userid
if (!i_username && !i_userid) {
snprintf(reply, siz, "failed.invalid/missing userinfo");
LOGERR("%s.%s", id, reply);
return strdup(reply);
}
// A zero length status re-enables it
i_status = require_name(trf_root, "status", 0, NULL, reply, siz);
if (!i_status)
return strdup(reply);
status = transfer_data(i_status);
K_RLOCK(users_free);
if (i_username)
u_item = find_users(transfer_data(i_username));
else {
TXT_TO_BIGINT("userid", transfer_data(i_userid), userid);
u_item = find_userid(userid);
}
K_RUNLOCK(users_free);
if (!u_item)
ok = false;
else {
ok = users_update(conn, u_item,
NULL, NULL,
NULL,
by, code, inet, now,
trf_root,
status);
}
if (!ok) {
LOGERR("%s() %s.failed.DBE", __func__, id);
return strdup("failed.DBE");
}
DATA_USERS(users, u_item);
snprintf(reply, siz, "ok.updated %"PRId64" %s status %s",
users->userid,
users->username,
status[0] ? "disabled" : "enabled");
LOGWARNING("%s.%s", id, reply);
return strdup(reply);
}
// TODO: limit access by having seperate sockets for each // TODO: limit access by having seperate sockets for each
#define ACCESS_POOL "p" #define ACCESS_POOL "p"
#define ACCESS_SYSTEM "s" #define ACCESS_SYSTEM "s"
@ -3492,7 +3558,8 @@ struct CMDS ckdb_cmds[] = {
{ CMD_GETOPTS, "getopts", false, false, cmd_getopts, ACCESS_WEB }, { CMD_GETOPTS, "getopts", false, false, cmd_getopts, ACCESS_WEB },
{ CMD_SETOPTS, "setopts", false, false, cmd_setopts, ACCESS_WEB }, { CMD_SETOPTS, "setopts", false, false, cmd_setopts, ACCESS_WEB },
{ CMD_DSP, "dsp", false, false, cmd_dsp, ACCESS_SYSTEM }, { CMD_DSP, "dsp", false, false, cmd_dsp, ACCESS_SYSTEM },
{ CMD_STATS, "stats", true, false, cmd_stats, ACCESS_SYSTEM }, { CMD_STATS, "stats", true, false, cmd_stats, ACCESS_SYSTEM ACCESS_WEB },
{ CMD_PPLNS, "pplns", false, false, cmd_pplns, ACCESS_SYSTEM }, { CMD_PPLNS, "pplns", false, false, cmd_pplns, ACCESS_SYSTEM ACCESS_WEB },
{ CMD_USERSTATUS,"userstatus", false, false, cmd_userstatus, ACCESS_SYSTEM ACCESS_WEB },
{ CMD_END, NULL, false, false, NULL, NULL } { CMD_END, NULL, false, false, NULL, NULL }
}; };

28
src/ckdb_dbio.c

@ -304,9 +304,10 @@ cleanup:
return lastid; return lastid;
} }
bool users_pass_email(PGconn *conn, K_ITEM *u_item, char *oldhash, // status was added to the end so type checking intercepts new mistakes
char *newhash, char *email, char *by, char *code, bool users_update(PGconn *conn, K_ITEM *u_item, char *oldhash,
char *inet, tv_t *cd, K_TREE *trf_root) char *newhash, char *email, char *by, char *code,
char *inet, tv_t *cd, K_TREE *trf_root, char *status)
{ {
ExecStatusType rescode; ExecStatusType rescode;
bool conned = false; bool conned = false;
@ -315,7 +316,7 @@ bool users_pass_email(PGconn *conn, K_ITEM *u_item, char *oldhash,
USERS *row, *users; USERS *row, *users;
char *upd, *ins; char *upd, *ins;
bool ok = false; bool ok = false;
char *params[5 + HISTORYDATECOUNT]; char *params[6 + HISTORYDATECOUNT];
bool hash; bool hash;
int n, par = 0; int n, par = 0;
@ -337,14 +338,18 @@ bool users_pass_email(PGconn *conn, K_ITEM *u_item, char *oldhash,
DATA_USERS(row, item); DATA_USERS(row, item);
memcpy(row, users, sizeof(*row)); memcpy(row, users, sizeof(*row));
// Update one, leave the other
// Update each one supplied
if (hash) { if (hash) {
// New salt each password change // New salt each password change
make_salt(row); make_salt(row);
password_hash(row->username, newhash, row->salt, password_hash(row->username, newhash, row->salt,
row->passwordhash, sizeof(row->passwordhash)); row->passwordhash, sizeof(row->passwordhash));
} else }
if (email)
STRNCPY(row->emailaddress, email); STRNCPY(row->emailaddress, email);
if (status)
STRNCPY(row->status, status);
HISTORYDATEINIT(row, cd, by, code, inet); HISTORYDATEINIT(row, cd, by, code, inet);
HISTORYDATETRANSFER(trf_root, row); HISTORYDATETRANSFER(trf_root, row);
@ -384,21 +389,22 @@ bool users_pass_email(PGconn *conn, K_ITEM *u_item, char *oldhash,
par = 0; par = 0;
params[par++] = bigint_to_buf(row->userid, NULL, 0); params[par++] = bigint_to_buf(row->userid, NULL, 0);
params[par++] = tv_to_buf(cd, NULL, 0); params[par++] = tv_to_buf(cd, NULL, 0);
// Copy them both in - one will be new and one will be old // Copy them all in - at least one will be new
params[par++] = str_to_buf(row->status, NULL, 0);
params[par++] = str_to_buf(row->emailaddress, NULL, 0); params[par++] = str_to_buf(row->emailaddress, NULL, 0);
params[par++] = str_to_buf(row->passwordhash, NULL, 0); params[par++] = str_to_buf(row->passwordhash, NULL, 0);
// New salt for each password change (or recopy old) // New salt for each password change (or recopy old)
params[par++] = str_to_buf(row->salt, NULL, 0); params[par++] = str_to_buf(row->salt, NULL, 0);
HISTORYDATEPARAMS(params, par, row); HISTORYDATEPARAMS(params, par, row);
PARCHKVAL(par, 5 + HISTORYDATECOUNT, params); // 10 as per ins PARCHKVAL(par, 6 + HISTORYDATECOUNT, params); // 11 as per ins
ins = "insert into users " ins = "insert into users "
"(userid,username,status,emailaddress,joineddate," "(userid,username,status,emailaddress,joineddate,"
"passwordhash,secondaryuserid,salt" "passwordhash,secondaryuserid,salt"
HISTORYDATECONTROL ") select " HISTORYDATECONTROL ") select "
"userid,username,status,$3,joineddate," "userid,username,$3,$4,joineddate,"
"$4,secondaryuserid,$5," "$5,secondaryuserid,$6,"
"$6,$7,$8,$9,$10 from users where " "$7,$8,$9,$10,$11 from users where "
"userid=$1 and expirydate=$2"; "userid=$1 and expirydate=$2";
res = PQexecParams(conn, ins, par, NULL, (const char **)params, NULL, NULL, 0, CKPQ_WRITE); res = PQexecParams(conn, ins, par, NULL, (const char **)params, NULL, NULL, 0, CKPQ_WRITE);

Loading…
Cancel
Save