在创建时生成唯一 uidnumber / gidnumber 的 AD 插件或实用程序

在创建时生成唯一 uidnumber / gidnumber 的 AD 插件或实用程序

我正在寻找:

该插件将在创建时自动为新用户生成唯一的 uidNumber 属性值,并为新组生成唯一的 gidNumber 属性值。

可配置的用户/组管理应用程序,可以生成上述唯一值以及填充 Linux 集成所需的各种其他属性

我们目前正在使用自己开发的脚本和网页来完成所有这些工作,但我们正在寻找一些不需要维护且更加完善的东西。

有人知道符合要求的好工具吗?

谢谢!

答案1

我不知道有任何现有工具可以在创作时真正触发。不过,正如 Nic 提到的,理论上可以编写一些可以做到这一点的东西。

但实际上,在已经自动化的流程之外创建用户/组的频率是多少?如果还没有,则应增强您现有的配置流程以添加相关的RFC2307属性也描述在这篇 TechNet 博客文章。对于手动创建的落后者,您可以按照您喜欢的任意间隔运行脚本,查找缺少属性的对象并根据需要填充它们。

在我们的环境中,我们的脚本每 5 分钟在担任 PDC 模拟器角色的 DC 上运行一次。但我们可能可以将其降低到每分钟一次,而不会产生太多额外影响。我们还从基于对象的 SID 而不是简单的自动递增值的算法生成 UID/GID 值。它的好处是它们在域/林之间保证*唯一,我们不需要进行任何查找来查找下一个值或确保我们要使用的值尚未被使用。如果您愿意,我可以发布该功能。但听起来你们可能已经有自己的系统了。

*保证 = 尽可能保证不会创建两个具有相同随机生成的域 ID 的域。

编辑:根据要求,这是我们用来从 SID 生成 UID/GID 的 Powershell 函数。

function Get-UidFromSid()
{
    [CmdletBinding()]
    param(
        [Parameter(Mandatory=$true,Position=0,ValueFromPipeline,ValueFromPipelineByPropertyName)]
        [System.Security.Principal.SecurityIdentifier]$sid
    )

    # convert sid to byte array
    $sidBytes = New-Object byte[] $sid.BinaryLength
    $sid.GetBinaryForm($sidBytes, 0)
    Write-Verbose ("SID bytes: $([System.BitConverter]::ToString($sidBytes))")

    # copy the sections we need
    $ridDomainBytes = New-Object byte[] 8
    [System.Array]::Copy($sidBytes, 16, $ridDomainBytes, 0, 4)
    $ridUserBytes = New-Object byte[] 8
    [System.Array]::Copy($sidBytes, 24, $ridUserBytes, 0, 4)
    Write-Verbose ("Domain portion: $([System.BitConverter]::ToString($ridDomainBytes))")
    Write-Verbose ("User portion: $([System.BitConverter]::ToString($ridUserBytes))")

    # fix endian'ness if necessary
    if (![System.BitConverter]::IsLittleEndian)
    {
        [System.Array]::Reverse($ridDomainBytes)
        [System.Array]::Reverse($ridUserBytes)
    }

    # convert the byte arrays to longs
    $ridDomain = [System.BitConverter]::ToInt64($ridDomainBytes, 0);
    $ridUser = [System.BitConverter]::ToInt64($ridUserBytes, 0);
    Write-Verbose "Domain(Int64) = $ridDomain, User(Int64) = $ridUser"

    # Now we're going to use the first 9 bits of the domain rid followed by the
    # first 22 bits of the user rid to make a single 31 bit integer (32-bit signed)
    # that will be the new unique UID value for this SID
    $ridDomain = ($ridDomain -band 0x1ff) -shl 22
    $ridUser = $ridUser -band 0x3fffff
    Write-Verbose "Domain(Int64) = $ridDomain, User(Int64) = $ridUser"

    return ($ridDomain + $ridUser)

<#
.SYNOPSIS
    Calculate the UID value for a Windows SID.

.DESCRIPTION
    This function duplicates Centrify's algorithm for generating unique UID
    values for Active Directory users and groups. The original algorithm was
    provided by Centrify and ported to PowerShell by Ryan Bolger.

.PARAMETER sid
    The SecurityIdentifier (SID) object to calculate against.

.OUTPUTS
    System.Int32 value of the resulting UID.

.EXAMPLE
    Get-UidFromSid ([System.Security.Principal.SecurityIdentifier]'S-1-5-21-3040497277-3966670145-4188292625-1137')

    Calculate a UID from a fictional SID.

.EXAMPLE
    Get-ADUser myuser | Get-UidFromSid

    Calculate a UID from an existing Active Directory user via pipeline input.
#>

}

这里有一个GitHub 要点还有一些额外的实现,如 C#、Bash 和 Python。

答案2

您可以从 PowerShell 脚本中分配 gidNumber 属性。要使其自动化,请将脚本作为计划任务调用。我编写了一个名为初始化 GroupGids它为 AD 组分配唯一的 gid,并且可以使用参数针对不同的环境进行定制。

但基本上,您只需在 PowerShell 中执行类似的事情即可。

# Find the highest GID used on any group in the domain
$highGid = Get-ADGroup -LDAPFilter "(gidNumber=*)" -Properties gidNumber |
    Measure-Object -Property gidNumber -Maximum |
    Select-Object -ExpandProperty Maximum

# Avoid assigning GIDs below 1000
$highGid = [Math]::max( $highGid, 1000 )

# Find every security group without a gidNumber, and give it one.
Get-ADGroup -LDAPFilter "(!gidNumber=*)" |
    ? {$_.GroupCategory -eq "Security"} |
    $groups | Set-ADGroup -Add @{ gidNumber=++$highGid }

这也可以轻松适用于用户和 uidNumbers。

如果你希望立即分配 uids/gids,Microsoft 有一个有趣的技术说明通过 LDAP 监听来自 Active Directory 的更改通知。不过我认为这对于 PowerShell 来说有点太复杂了。

答案3

受到这里的答案以及 Samba 邮件列表的启发,我编写了一个名为 ADAM 的工具来分配 UID/GID 值:

https://gitlab.com/JonathonReinhart/adam

目前(2019 年 6 月),此功能仅在 Linux 上进行了测试,针对 Samba Active Directory 域运行。但是,它应该可以在 Windows 和/或 Windows Active Directory 域上运行(或非常接近)。

相关内容