]> mj.ucw.cz Git - subauth.git/blobdiff - server/cmd.c
Account management using password authentication
[subauth.git] / server / cmd.c
index 8959d078c8d94e52871e5b28c646be9bfbc0d43f..45873eda3b3ed48ba625c71c9508a82313b3ffa5 100644 (file)
@@ -91,6 +91,14 @@ static const char *cmd_need_string(struct client *c, const char *key)
   return val;
 }
 
+static uint cmd_need_uint(struct client *c, const char *key)
+{
+  uint val = 0;
+  if (!get_uint(c->request, key, &val))
+    cmd_error(c, "Missing %s", key);
+  return val;
+}
+
 static struct auth_zone *cmd_need_zone(struct client *c)
 {
   const char *name = cmd_need_string(c, "zone");
@@ -128,8 +136,64 @@ static const char *cmd_need_target_login(struct client *c)
     }
 }
 
+static void cmd_passwd_auth_fake(struct client *c, const char *passwd)
+{
+  auth_check_token(auth_fake_token, passwd);
+  cmd_error(c, "Invalid password");
+}
+
+static struct auth_acct *cmd_need_passwd_auth_acct(struct client *c, const char *passwd)
+{
+  struct auth_zone *az = cmd_need_zone(c);
+  const char *login = cmd_need_string(c, "login");
+  if (!az->allow_passwd_auth || !az->allow_passwd)
+    {
+      msg(L_INFO, "Password authentication denied by zone configuration: login=<%s> zone=<%s> uid=<%u>", login, az->name, c->uid);
+      cmd_error(c, "This zone does not allow password authentication for management");
+    }
+
+  struct auth_user *au = auth_find_user(login, 0);
+  if (!au)
+    {
+      msg(L_INFO, "Password authentication failed: No user=<%s> uid=<%u>", login, c->uid);
+      cmd_passwd_auth_fake(c, passwd);
+    }
+
+  struct auth_acct *aa = auth_find_acct(au, az, 0);
+  if (!aa)
+    {
+      msg(L_INFO, "Password authentication failed: No account user=<%s> zone=<%s> uid=<%u>", login, az->name, c->uid);
+      cmd_passwd_auth_fake(c, passwd);
+    }
+  if (!aa->allow_passwd_auth)
+    {
+      msg(L_INFO, "Password authentication failed: Not allowed by user=<%s> zone=<%s> uid=<%u>", login, az->name, c->uid);
+      cmd_passwd_auth_fake(c, passwd);
+    }
+
+  struct auth_token *at = auth_find_token_passwd(aa);
+  if (!at)
+    {
+      msg(L_INFO, "Password authentication failed: No password user=<%s> zone=<%s> uid=<%u>", login, az->name, c->uid);
+      cmd_passwd_auth_fake(c, passwd);
+    }
+
+  if (!auth_check_token(at, passwd))
+    {
+      msg(L_INFO, "Password authentication failed: Wrong password for user=<%s> zone=<%s> uid=<%u>", login, az->name, c->uid);
+      cmd_error(c, "Invalid password");
+    }
+
+  msg(L_INFO, "Password authentication successful: user=<%s> zone=<%s> uid=<%u>", login, az->name, c->uid);
+  return aa;
+}
+
 static struct auth_acct *cmd_need_target_acct(struct client *c)
 {
+  const char *auth_passwd = get_string(c->request, "auth-passwd");
+  if (auth_passwd)
+    return cmd_need_passwd_auth_acct(c, auth_passwd);
+
   const char *login = cmd_need_target_login(c);
   struct auth_zone *az = cmd_need_zone(c);
 
@@ -453,6 +517,21 @@ static void cmd_login(struct client *c)
   cmd_ok(c);
 }
 
+static void cmd_allow_passwd_auth(struct client *c)
+{
+  struct auth_acct *aa = cmd_need_target_acct(c);
+  uint allow = cmd_need_uint(c, "allow");
+  if (!aa->zone->allow_passwd_auth)
+    cmd_error(c, "This zone does not allow password authentication for management");
+
+  msg(L_INFO, "Setting account password authentication: allow-passwd-auth=<%u> login=<%s> zone=<%s>", !!allow, aa->user->login, aa->zone->name);
+
+  aa->allow_passwd_auth = !!allow;
+
+  db_write();
+  cmd_ok(c);
+}
+
 static void cmd_list_accts(struct client *c)
 {
   const char *login = cmd_need_target_login(c);
@@ -474,6 +553,7 @@ static void cmd_list_accts(struct client *c)
       struct json_node *ja = json_new_object(js);
       json_array_append(jas, ja);
       set_string(c, ja, "zone", aa->zone->name);
+      set_uint(c, ja, "allow-passwd-auth", aa->zone->allow_passwd_auth && aa->allow_passwd_auth);
 
       struct json_node *jts = json_new_array(js);
       json_object_set(ja, "tokens", jts);
@@ -516,6 +596,7 @@ static void cmd_list_zones(struct client *c)
       set_string(c, jz, "desc", az->desc);
       set_uint(c, jz, "allow-passwd", az->allow_passwd);
       set_uint(c, jz, "allow-tokens", az->allow_tokens);
+      set_uint(c, jz, "allow-passwd-auth", az->allow_passwd_auth);
       set_uint(c, jz, "max-temp-validity", az->max_temp_validity);
     }
 
@@ -528,18 +609,19 @@ struct command {
 };
 
 static const struct command command_table[] = {
-  { "nop",             cmd_nop },
-  { "create-acct",     cmd_create_acct },
-  { "delete-acct",     cmd_delete_acct },
-  { "create-token",    cmd_create_token },
-  { "delete-token",    cmd_delete_token },
-  { "change-token",    cmd_change_token },
-  { "set-passwd",      cmd_set_passwd },
-  { "delete-passwd",   cmd_delete_passwd },
-  { "create-temp",     cmd_create_temp },
-  { "login",           cmd_login },
-  { "list-accts",      cmd_list_accts },
-  { "list-zones",      cmd_list_zones },
+  { "nop",                     cmd_nop },
+  { "create-acct",             cmd_create_acct },
+  { "delete-acct",             cmd_delete_acct },
+  { "create-token",            cmd_create_token },
+  { "delete-token",            cmd_delete_token },
+  { "change-token",            cmd_change_token },
+  { "set-passwd",              cmd_set_passwd },
+  { "delete-passwd",           cmd_delete_passwd },
+  { "create-temp",             cmd_create_temp },
+  { "login",                   cmd_login },
+  { "allow-passwd-auth",       cmd_allow_passwd_auth },
+  { "list-accts",              cmd_list_accts },
+  { "list-zones",              cmd_list_zones },
 };
 
 void cmd_dispatch(struct client *c)