Commit 15dfcd454cb99fd8c65b6ecda24acd9dabd570a7

Authored by Jan Kiszka
Committed by Anthony Liguori
1 parent f3353c6b

monitor: Refactor acl commnds

Refactor the ACL monitor interface to make full use of the monitor
command dispatcher. This also gives proper help formatting and command
completion. Note that 'acl allow' and 'acl deny' were combined to
'acl_add aclname match allow|deny [index]' for consistency reasons.

Signed-off-by: Jan Kiszka <jan.kiszka@siemens.com>
Signed-off-by: Anthony Liguori <aliguori@us.ibm.com>
Showing 2 changed files with 96 additions and 76 deletions
monitor.c
... ... @@ -1579,60 +1579,79 @@ static void do_info_balloon(Monitor *mon)
1579 1579 monitor_printf(mon, "balloon: actual=%d\n", (int)(actual >> 20));
1580 1580 }
1581 1581  
1582   -static void do_acl(Monitor *mon,
1583   - const char *command,
1584   - const char *aclname,
1585   - const char *match,
1586   - int has_index,
1587   - int index)
  1582 +static qemu_acl *find_acl(Monitor *mon, const char *name)
1588 1583 {
1589   - qemu_acl *acl;
  1584 + qemu_acl *acl = qemu_acl_find(name);
1590 1585  
1591   - acl = qemu_acl_find(aclname);
1592 1586 if (!acl) {
1593   - monitor_printf(mon, "acl: unknown list '%s'\n", aclname);
1594   - return;
  1587 + monitor_printf(mon, "acl: unknown list '%s'\n", name);
1595 1588 }
  1589 + return acl;
  1590 +}
  1591 +
  1592 +static void do_acl_show(Monitor *mon, const char *aclname)
  1593 +{
  1594 + qemu_acl *acl = find_acl(mon, aclname);
  1595 + qemu_acl_entry *entry;
  1596 + int i = 0;
1596 1597  
1597   - if (strcmp(command, "show") == 0) {
1598   - int i = 0;
1599   - qemu_acl_entry *entry;
  1598 + if (acl) {
1600 1599 monitor_printf(mon, "policy: %s\n",
1601 1600 acl->defaultDeny ? "deny" : "allow");
1602 1601 TAILQ_FOREACH(entry, &acl->entries, next) {
1603 1602 i++;
1604 1603 monitor_printf(mon, "%d: %s %s\n", i,
1605   - entry->deny ? "deny" : "allow",
1606   - entry->match);
  1604 + entry->deny ? "deny" : "allow", entry->match);
1607 1605 }
1608   - } else if (strcmp(command, "reset") == 0) {
  1606 + }
  1607 +}
  1608 +
  1609 +static void do_acl_reset(Monitor *mon, const char *aclname)
  1610 +{
  1611 + qemu_acl *acl = find_acl(mon, aclname);
  1612 +
  1613 + if (acl) {
1609 1614 qemu_acl_reset(acl);
1610 1615 monitor_printf(mon, "acl: removed all rules\n");
1611   - } else if (strcmp(command, "policy") == 0) {
1612   - if (!match) {
1613   - monitor_printf(mon, "acl: missing policy parameter\n");
1614   - return;
1615   - }
  1616 + }
  1617 +}
  1618 +
  1619 +static void do_acl_policy(Monitor *mon, const char *aclname,
  1620 + const char *policy)
  1621 +{
  1622 + qemu_acl *acl = find_acl(mon, aclname);
1616 1623  
1617   - if (strcmp(match, "allow") == 0) {
  1624 + if (acl) {
  1625 + if (strcmp(policy, "allow") == 0) {
1618 1626 acl->defaultDeny = 0;
1619 1627 monitor_printf(mon, "acl: policy set to 'allow'\n");
1620   - } else if (strcmp(match, "deny") == 0) {
  1628 + } else if (strcmp(policy, "deny") == 0) {
1621 1629 acl->defaultDeny = 1;
1622 1630 monitor_printf(mon, "acl: policy set to 'deny'\n");
1623 1631 } else {
1624   - monitor_printf(mon, "acl: unknown policy '%s', expected 'deny' or 'allow'\n", match);
  1632 + monitor_printf(mon, "acl: unknown policy '%s', "
  1633 + "expected 'deny' or 'allow'\n", policy);
1625 1634 }
1626   - } else if ((strcmp(command, "allow") == 0) ||
1627   - (strcmp(command, "deny") == 0)) {
1628   - int deny = strcmp(command, "deny") == 0 ? 1 : 0;
1629   - int ret;
  1635 + }
  1636 +}
1630 1637  
1631   - if (!match) {
1632   - monitor_printf(mon, "acl: missing match parameter\n");
  1638 +static void do_acl_add(Monitor *mon, const char *aclname,
  1639 + const char *match, const char *policy,
  1640 + int has_index, int index)
  1641 +{
  1642 + qemu_acl *acl = find_acl(mon, aclname);
  1643 + int deny, ret;
  1644 +
  1645 + if (acl) {
  1646 + if (strcmp(policy, "allow") == 0) {
  1647 + deny = 0;
  1648 + } else if (strcmp(policy, "deny") == 0) {
  1649 + deny = 1;
  1650 + } else {
  1651 + monitor_printf(mon, "acl: unknown policy '%s', "
  1652 + "expected 'deny' or 'allow'\n", policy);
1633 1653 return;
1634 1654 }
1635   -
1636 1655 if (has_index)
1637 1656 ret = qemu_acl_insert(acl, deny, match, index);
1638 1657 else
... ... @@ -1641,21 +1660,20 @@ static void do_acl(Monitor *mon,
1641 1660 monitor_printf(mon, "acl: unable to add acl entry\n");
1642 1661 else
1643 1662 monitor_printf(mon, "acl: added rule at position %d\n", ret);
1644   - } else if (strcmp(command, "remove") == 0) {
1645   - int ret;
  1663 + }
  1664 +}
1646 1665  
1647   - if (!match) {
1648   - monitor_printf(mon, "acl: missing match parameter\n");
1649   - return;
1650   - }
  1666 +static void do_acl_remove(Monitor *mon, const char *aclname, const char *match)
  1667 +{
  1668 + qemu_acl *acl = find_acl(mon, aclname);
  1669 + int ret;
1651 1670  
  1671 + if (acl) {
1652 1672 ret = qemu_acl_remove(acl, match);
1653 1673 if (ret < 0)
1654 1674 monitor_printf(mon, "acl: no matching acl entry\n");
1655 1675 else
1656 1676 monitor_printf(mon, "acl: removed rule at position %d\n", ret);
1657   - } else {
1658   - monitor_printf(mon, "acl: unknown command '%s'\n", command);
1659 1677 }
1660 1678 }
1661 1679  
... ...
qemu-monitor.hx
... ... @@ -569,48 +569,50 @@ STEXI
569 569 Change watchdog action.
570 570 ETEXI
571 571  
572   - { "acl", "sss?i?", do_acl, "<command> <aclname> [<match> [<index>]]\n",
573   - "acl show vnc.username\n"
574   - "acl policy vnc.username deny\n"
575   - "acl allow vnc.username fred\n"
576   - "acl deny vnc.username bob\n"
577   - "acl reset vnc.username\n" },
  572 + { "acl_show", "s", do_acl_show, "aclname",
  573 + "list rules in the access control list" },
578 574 STEXI
579   -@item acl @var{subcommand} @var{aclname} @var{match} @var{index}
580   -
581   -Manage access control lists for network services. There are currently
582   -two named access control lists, @var{vnc.x509dname} and @var{vnc.username}
583   -matching on the x509 client certificate distinguished name, and SASL
584   -username respectively.
  575 +@item acl_show @var{aclname}
  576 +List all the matching rules in the access control list, and the default
  577 +policy. There are currently two named access control lists,
  578 +@var{vnc.x509dname} and @var{vnc.username} matching on the x509 client
  579 +certificate distinguished name, and SASL username respectively.
  580 +ETEXI
585 581  
586   -@table @option
587   -@item acl show <aclname>
588   -list all the match rules in the access control list, and the default
589   -policy
590   -@item acl policy <aclname> @code{allow|deny}
591   -set the default access control list policy, used in the event that
  582 + { "acl_policy", "ss", do_acl_policy, "aclname allow|deny",
  583 + "set default access control list policy" },
  584 +STEXI
  585 +@item acl_policy @var{aclname] @code{allow|deny}
  586 +Set the default access control list policy, used in the event that
592 587 none of the explicit rules match. The default policy at startup is
593   -always @code{deny}
594   -@item acl allow <aclname> <match> [<index>]
595   -add a match to the access control list, allowing access. The match will
596   -normally be an exact username or x509 distinguished name, but can
597   -optionally include wildcard globs. eg @code{*@@EXAMPLE.COM} to allow
598   -all users in the @code{EXAMPLE.COM} kerberos realm. The match will
599   -normally be appended to the end of the ACL, but can be inserted
600   -earlier in the list if the optional @code{index} parameter is supplied.
601   -@item acl deny <aclname> <match> [<index>]
602   -add a match to the access control list, denying access. The match will
603   -normally be an exact username or x509 distinguished name, but can
604   -optionally include wildcard globs. eg @code{*@@EXAMPLE.COM} to allow
605   -all users in the @code{EXAMPLE.COM} kerberos realm. The match will
  588 +always @code{deny}.
  589 +ETEXI
  590 +
  591 + { "acl_add", "sssi?", do_acl_add, "aclname match allow|deny [index]",
  592 + "add a match rule to the access control list" },
  593 +STEXI
  594 +@item acl_allow @var{aclname} @var{match} @code{allow|deny} [@var{index}]
  595 +Add a match rule to the access control list, allowing or denying access.
  596 +The match will normally be an exact username or x509 distinguished name,
  597 +but can optionally include wildcard globs. eg @code{*@@EXAMPLE.COM} to
  598 +allow all users in the @code{EXAMPLE.COM} kerberos realm. The match will
606 599 normally be appended to the end of the ACL, but can be inserted
607   -earlier in the list if the optional @code{index} parameter is supplied.
608   -@item acl remove <aclname> <match>
609   -remove the specified match rule from the access control list.
610   -@item acl reset <aclname>
611   -remove all matches from the access control list, and set the default
  600 +earlier in the list if the optional @var{index} parameter is supplied.
  601 +ETEXI
  602 +
  603 + { "acl_remove", "ss", do_acl_remove, "aclname match",
  604 + "remove a match rule from the access control list" },
  605 +STEXI
  606 +@item acl_remove @var{aclname} @var{match}
  607 +Remove the specified match rule from the access control list.
  608 +ETEXI
  609 +
  610 + { "acl_reset", "s", do_acl_reset, "aclname",
  611 + "reset the access control list" },
  612 +STEXI
  613 +@item acl_remove @var{aclname} @var{match}
  614 +Remove all matches from the access control list, and set the default
612 615 policy back to @code{deny}.
613   -@end table
614 616 ETEXI
615 617  
616 618 STEXI
... ...