Skip to content

Commit

Permalink
Desktop access: add teleport.dev/ou label
Browse files Browse the repository at this point in the history
Automatically label discovered desktops with the LDAP
organizational unit they belong to. This expands the
ability to define RBAC rules based on OU.

Since the organizationalUnit attribute is often unspecified,
we compute the OU by trimming the CN from the full DN.

Updates #12326
  • Loading branch information
zmb3 committed May 6, 2022
1 parent bb22269 commit 8190f7f
Show file tree
Hide file tree
Showing 2 changed files with 28 additions and 11 deletions.
28 changes: 21 additions & 7 deletions lib/srv/desktop/discovery.go
Original file line number Diff line number Diff line change
Expand Up @@ -34,6 +34,8 @@ import (
// see: https://docs.microsoft.com/en-us/windows/win32/adschema/c-computer#windows-server-2012-attributes
var computerAttribtes = []string{
attrName,
attrCommonName,
attrDistinguishedName,
attrDNSHostName,
attrObjectGUID,
attrOS,
Expand All @@ -53,12 +55,14 @@ const (
writableDomainControllerGroupID = "516"
readOnlyDomainControllerGroupID = "521"

attrName = "name"
attrDNSHostName = "dNSHostName" // unusual capitalization is correct
attrObjectGUID = "objectGUID"
attrOS = "operatingSystem"
attrOSVersion = "operatingSystemVersion"
attrPrimaryGroupID = "primaryGroupID"
attrName = "name"
attrCommonName = "cn"
attrDistinguishedName = "distinguishedName"
attrDNSHostName = "dNSHostName" // unusual capitalization is correct
attrObjectGUID = "objectGUID"
attrOS = "operatingSystem"
attrOSVersion = "operatingSystemVersion"
attrPrimaryGroupID = "primaryGroupID"
)

// startDesktopDiscovery starts fetching desktops from LDAP, periodically
Expand Down Expand Up @@ -177,11 +181,21 @@ func (s *WindowsService) deleteDesktop(ctx context.Context, r types.ResourceWith
}

func applyLabelsFromLDAP(entry *ldap.Entry, labels map[string]string) {
labels[types.OriginLabel] = types.OriginDynamic

labels[types.TeleportNamespace+"/dns_host_name"] = entry.GetAttributeValue(attrDNSHostName)
labels[types.TeleportNamespace+"/computer_name"] = entry.GetAttributeValue(attrName)
labels[types.TeleportNamespace+"/os"] = entry.GetAttributeValue(attrOS)
labels[types.TeleportNamespace+"/os_version"] = entry.GetAttributeValue(attrOSVersion)
labels[types.OriginLabel] = types.OriginDynamic

dn := entry.GetAttributeValue(attrDistinguishedName)
cn := entry.GetAttributeValue(attrCommonName)

if len(dn) > 0 && len(cn) > 0 {
ou := strings.TrimPrefix(dn, "CN="+cn+",")
labels[types.TeleportNamespace+"/ou"] = ou
}

switch entry.GetAttributeValue(attrPrimaryGroupID) {
case writableDomainControllerGroupID, readOnlyDomainControllerGroupID:
labels[types.TeleportNamespace+"/is_domain_controller"] = "true"
Expand Down
11 changes: 7 additions & 4 deletions lib/srv/desktop/discovery_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -63,10 +63,12 @@ func TestDiscoveryLDAPFilter(t *testing.T) {
func TestAppliesLDAPLabels(t *testing.T) {
l := make(map[string]string)
entry := ldap.NewEntry("CN=test,DC=example,DC=com", map[string][]string{
attrDNSHostName: {"foo.example.com"},
attrName: {"foo"},
attrOS: {"Windows Server"},
attrOSVersion: {"6.1"},
attrDNSHostName: {"foo.example.com"},
attrName: {"foo"},
attrOS: {"Windows Server"},
attrOSVersion: {"6.1"},
attrDistinguishedName: {"CN=foo,OU=IT,DC=goteleport,DC=com"},
attrCommonName: {"foo"},
})
applyLabelsFromLDAP(entry, l)

Expand All @@ -75,6 +77,7 @@ func TestAppliesLDAPLabels(t *testing.T) {
require.Equal(t, l[types.TeleportNamespace+"/computer_name"], "foo")
require.Equal(t, l[types.TeleportNamespace+"/os"], "Windows Server")
require.Equal(t, l[types.TeleportNamespace+"/os_version"], "6.1")
require.Equal(t, l[types.TeleportNamespace+"/ou"], "OU=IT,DC=goteleport,DC=com")
}

func TestLabelsDomainControllers(t *testing.T) {
Expand Down

0 comments on commit 8190f7f

Please sign in to comment.