diff options
author | Dennis Kaarsemaker <dennis@kaarsemaker.net> | 2016-02-22 21:04:10 +0100 |
---|---|---|
committer | Dennis Kaarsemaker <dennis@kaarsemaker.net> | 2016-03-23 07:44:13 +0100 |
commit | 3ac6d9fe93279d74d36a6bf2b6e2ba182ed3bf34 (patch) | |
tree | 681d3c36caa3f2680ca5b810c09f3d1f54a868cd | |
parent | d701547347b15bd76f19fcf667cbf8e5c1219cbb (diff) |
Support for locked-down accounts
In certain situations, e.g. when working with pregenerated
configurations, it is useful to be able lock down accounts so they
cannot be deleted and authentication information (user, password,
server) cannot be changed.
We mark such sensitive settings with ACC_SET_LOCKABLE and will refuse to
change them if the account is locked by setting the ACC_FLAG_LOCKED
flag.
This flag is stored in the xml files as account attribute locked="true".
-rw-r--r-- | protocols/account.c | 4 | ||||
-rw-r--r-- | protocols/account.h | 2 | ||||
-rw-r--r-- | root_commands.c | 8 | ||||
-rw-r--r-- | storage_xml.c | 9 |
4 files changed, 19 insertions, 4 deletions
diff --git a/protocols/account.c b/protocols/account.c index fcafe215..e25e40c7 100644 --- a/protocols/account.c +++ b/protocols/account.c @@ -66,13 +66,13 @@ account_t *account_add(bee_t *bee, struct prpl *prpl, char *user, char *pass) s->flags |= SET_NOSAVE; /* Just for bw compatibility! */ s = set_add(&a->set, "password", NULL, set_eval_account, a); - s->flags |= SET_NOSAVE | SET_NULL_OK | SET_PASSWORD; + s->flags |= SET_NOSAVE | SET_NULL_OK | SET_PASSWORD | ACC_SET_LOCKABLE; s = set_add(&a->set, "tag", NULL, set_eval_account, a); s->flags |= SET_NOSAVE; s = set_add(&a->set, "username", NULL, set_eval_account, a); - s->flags |= SET_NOSAVE | ACC_SET_OFFLINE_ONLY; + s->flags |= SET_NOSAVE | ACC_SET_OFFLINE_ONLY | ACC_SET_LOCKABLE; set_setstr(&a->set, "username", user); /* Hardcode some more clever tag guesses. */ diff --git a/protocols/account.h b/protocols/account.h index 0e118680..bea8ca9f 100644 --- a/protocols/account.h +++ b/protocols/account.h @@ -62,6 +62,7 @@ int protocol_account_islocal(const char* protocol); typedef enum { ACC_SET_OFFLINE_ONLY = 0x02, /* Allow changes only if the acct is offline. */ ACC_SET_ONLINE_ONLY = 0x04, /* Allow changes only if the acct is online. */ + ACC_SET_LOCKABLE = 0x08 /* Setting cannot be changed if the account is locked down */ } account_set_flag_t; typedef enum { @@ -69,6 +70,7 @@ typedef enum { ACC_FLAG_STATUS_MESSAGE = 0x02, /* Supports status messages (without being away). */ ACC_FLAG_HANDLE_DOMAINS = 0x04, /* Contact handles need a domain portion. */ ACC_FLAG_LOCAL = 0x08, /* Contact list is local. */ + ACC_FLAG_LOCKED = 0x10, /* Account is locked (cannot be deleted, certain settings can't changed) */ } account_flag_t; #endif diff --git a/root_commands.c b/root_commands.c index 4ce964ae..f9c6e8e9 100644 --- a/root_commands.c +++ b/root_commands.c @@ -387,6 +387,9 @@ static int cmd_account_set_checkflags(irc_t *irc, set_t *s) } else if (!a->ic && s && s->flags & ACC_SET_ONLINE_ONLY) { irc_rootmsg(irc, "This setting can only be changed when the account is %s-line", "on"); return 0; + } else if (a->flags & ACC_FLAG_LOCKED && s && s->flags & ACC_SET_LOCKABLE) { + irc_rootmsg(irc, "This setting can not be changed for locked accounts"); + return 0; } return 1; @@ -546,7 +549,10 @@ static void cmd_account(irc_t *irc, char **cmd) } if (len >= 1 && g_strncasecmp(cmd[2], "del", len) == 0) { - if (a->ic) { + if (a->flags & ACC_FLAG_LOCKED) { + irc_rootmsg(irc, "Account is locked, can't delete"); + } + else if (a->ic) { irc_rootmsg(irc, "Account is still logged in, can't delete"); } else { account_del(irc->b, a); diff --git a/storage_xml.c b/storage_xml.c index 4237e10e..107983cf 100644 --- a/storage_xml.c +++ b/storage_xml.c @@ -85,7 +85,7 @@ static void handle_settings(struct xt_node *node, set_t **head) static xt_status handle_account(struct xt_node *node, gpointer data) { struct xml_parsedata *xd = data; - char *protocol, *handle, *server, *password = NULL, *autoconnect, *tag; + char *protocol, *handle, *server, *password = NULL, *autoconnect, *tag, *locked; char *pass_b64 = NULL; unsigned char *pass_cr = NULL; int pass_len, local = 0; @@ -98,6 +98,7 @@ static xt_status handle_account(struct xt_node *node, gpointer data) server = xt_find_attr(node, "server"); autoconnect = xt_find_attr(node, "autoconnect"); tag = xt_find_attr(node, "tag"); + locked = xt_find_attr(node, "locked"); protocol = xt_find_attr(node, "protocol"); if (protocol) { @@ -126,6 +127,9 @@ static xt_status handle_account(struct xt_node *node, gpointer data) if (local) { acc->flags |= ACC_FLAG_LOCAL; } + if (locked && !g_strcasecmp(locked, "true")) { + acc->flags |= ACC_FLAG_LOCKED; + } } else { g_free(pass_cr); g_free(password); @@ -319,6 +323,9 @@ struct xt_node *xml_generate(irc_t *irc) if (acc->server && acc->server[0]) { xt_add_attr(cur, "server", acc->server); } + if (acc->flags & ACC_FLAG_LOCKED) { + xt_add_attr(cur, "locked", "true"); + } g_free(pass_b64); |