AD plugin or utility that generates unique uidnumber / gidnumber on creation [closed]
I'm looking for either:
A plugin that will auto-generate a unique uidNumber attribute value for new users and a unique gidNumber attribute value for new groups upon creation.
A configurable user/group management application that can generate the unique values above as well as populate the various other attributes required for Linux integration
We present are using a home-grown script and web page to do all this, but we're looking for something that we don't have to maintain and a little more polished.
Anyone know of a good tool that fits the bill?
Thanks!
I don't know of any existing tools that actually trigger on creation. Though like Nic mentioned, it is hypothetically possible to write something that could do that.
But realistically, how often are users/groups getting created outside of already automated processes? If they're not already, your existing provisioning processes should be augmented to add the relevant RFC2307 attributes also described in this TechNet blog post. For the stragglers that are created manually, you can have a script run at whatever interval you like that looks for objects missing the attributes and populating them as necessary.
In our environment, the script we have runs every 5 min on the DC holding the PDC Emulator role. But we could probably drop it down to once a minute without much additional impact. We also generate our UID/GID values from an algorithm that's based on the object's SID rather than a simple auto-incrementing value. It has the benefit that they're guaranteed* unique between domains/forests and we don't need to do any lookups to find the next value or make sure the value we want to use isn't already in use. I can post that function if you'd like. But it sounds like you guys may already have your own system for that.
*Guaranteed = as much as you can guarantee that two domains won't be created with the same randomly generated domain ID.
Edit: By request, here's the Powershell function we use to generate UIDs/GIDs from a SID.
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.
#>
}
You could assign the gidNumber attribute from a PowerShell script. To make it automatic, call the script as a scheduled task. I wrote a cmdlet called Initialize-GroupGids which assigns unique gids to AD groups, and can be customized for different environments with parameters.
But basically, you can just to do something like this in 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 }
This could easily be adopted to work with users and uidNumbers too.
If you want the assignment of uids/gids to be instantaneous, Microsoft has an interesting technote about listening to change notifications from Active Directory via LDAP. I think that's a bit too sophisticated for PowerShell though.
With inspiration from answers here, and from the Samba mailing list, I wrote a tool called ADAM to assign UID/GID values:
https://gitlab.com/JonathonReinhart/adam
Currently (June 2019), this has only been tested on Linux, running against a Samba Active Directory domain. However, it should work (or be very close) running on Windows, and/or against a Windows Active Directory domain.