in Lib/Collectors/UserAccountCollector.cs [170:275]
internal void ExecuteOsX(CancellationToken cancellationToken)
{
Dictionary<string, GroupAccountObject> Groups = new Dictionary<string, GroupAccountObject>();
// Admin user details
var result = ExternalCommandRunner.RunExternalCommand("dscacheutil", "-q group -a name admin");
var lines = result.Split('\n');
// The fourth line is a list of usernames Formatted like: 'users: root gabe'
var admins = (lines[3].Split(':')[1]).Split(' ');
// details for all users
result = ExternalCommandRunner.RunExternalCommand("dscacheutil", "-q user");
var accountDetails = new Dictionary<string, UserAccountObject>();
// We initialize a new object. We know by the formatting of dscacheutil that we will never have a
// user without the name coming first, but we don't know the name yet.
var newUser = new UserAccountObject("");
foreach (var _line in result.Split('\n'))
{
if (cancellationToken.IsCancellationRequested) { break; }
var parts = _line.Split(':');
if (parts.Length < 2)
{
// There is a blank line separating each grouping of user data
continue;
}
// There is one space of padding, which we strip off here
var value = parts[1].Substring(1);
// dscacheutil prints the user information on multiple lines
switch (parts[0])
{
case "name":
accountDetails[value] = new UserAccountObject(value)
{
AccountType = (admins.Contains(value)) ? "administrator" : "standard",
Privileged = (admins.Contains(value))
};
newUser = accountDetails[value];
break;
case "password":
break;
case "uid":
newUser.UID = value;
break;
case "gid":
newUser.GID = value;
break;
case "dir":
newUser.HomeDirectory = value;
break;
case "shell":
newUser.Shell = value;
break;
case "gecos":
newUser.FullName = value;
break;
default:
break;
}
}
foreach (var username in accountDetails.Keys)
{
if (cancellationToken.IsCancellationRequested) { break; }
// Admin user details
string groupsRaw = string.Empty;
groupsRaw = ExternalCommandRunner.RunExternalCommand("groups", username);
var groups = groupsRaw.Split(' ');
foreach (var group in groups)
{
accountDetails[username].Groups.Add(group);
if (Groups.ContainsKey(group))
{
Groups[group].Users.Add(username);
}
else
{
Groups[group] = new GroupAccountObject(group);
Groups[group].Users.Add(username);
}
}
accountDetails[username].Groups.AddRange(groups);
HandleChange(accountDetails[username]);
}
foreach (var group in Groups)
{
if (cancellationToken.IsCancellationRequested) { break; }
HandleChange(group.Value);
}
}