Uploaded image for project: 'Kafka'
  1. Kafka
  2. KAFKA-3790

Default options when removing ACLs do not comply with documentation

    XMLWordPrintableJSON

Details

    • Bug
    • Status: Resolved
    • Minor
    • Resolution: Won't Fix
    • 0.9.0.1, 0.10.0.0
    • None
    • documentation, security
    • None
    • Patch

    Description

      When removing ACLs without providing options like principal, host or operation, we got a prompt for removing all the matching ACLs but when executing the command none get removed.

      The following commands can be used to reproduce the inconsistency:

      $ ./bin/kafka-acls.sh --authorizer-properties zookeeper.connect=localhost:2181 -list -topic test
      Current ACLs for resource `Topic:test`: 
      
      
      $ ./bin/kafka-acls.sh --authorizer-properties zookeeper.connect=localhost:2181 --add --allow-principal User:Alice --operation Write --topic test --allow-host 1.2.3.4
      Adding ACLs for resource `Topic:test`: 
       	User:Alice has Allow permission for operations: Write from hosts: 1.2.3.4 
      
      Current ACLs for resource `Topic:test`: 
       	User:Alice has Allow permission for operations: Write from hosts: 1.2.3.4 
      
      $ ./bin/kafka-acls.sh --authorizer-properties zookeeper.connect=localhost:2181 --remove --allow-principal User:Alice --topic test 
      Are you sure you want to remove ACLs: 
       	User:Alice has Allow permission for operations: All from hosts: * 
       from resource `Topic:test`? (y/n)
      y
      Current ACLs for resource `Topic:test`: 
       	User:Alice has Allow permission for operations: Write from hosts: 1.2.3.4 
      
      

      The Current ACLs for resource Topic:test is expected to be empty after the last command.

      Only a specific ACL (when all options mentioned above are provided) or else all the ACLs for a given resource (none of the options mentioned above are provided) can get removed as shown by the following code snippets:

        // AclCommand.scala
        ...
        private def removeAcl(opts: AclCommandOptions) {
          withAuthorizer(opts) { authorizer =>
            val resourceToAcl = getResourceToAcls(opts)
      
            for ((resource, acls) <- resourceToAcl) {
              if (acls.isEmpty) {
                if (confirmAction(opts, s"Are you sure you want to delete all ACLs for resource `${resource}`? (y/n)"))
                  authorizer.removeAcls(resource)
              } else {
                if (confirmAction(opts, s"Are you sure you want to remove ACLs: $Newline ${acls.map("\t" + _).mkString(Newline)} $Newline from resource `${resource}`? (y/n)"))
                  authorizer.removeAcls(acls, resource)
              }
            }
      
            listAcl(opts)
          }
        }
      ...
        // SimpleAclAuthorizer.scala
      ...
        override def removeAcls(aclsTobeRemoved: Set[Acl], resource: Resource): Boolean = {
           inWriteLock(lock) {
             updateResourceAcls(resource) { currentAcls =>
              currentAcls -- aclsTobeRemoved
             }
           }
         }
      

      A workaround consists of listing the ACL in order to know which exact one to remove which make the automation of ACL management trickier.

      Attachments

        Activity

          People

            Unassigned Unassigned
            yabon Sébastien Launay
            Votes:
            0 Vote for this issue
            Watchers:
            2 Start watching this issue

            Dates

              Created:
              Updated:
              Resolved: