YakkoWarner
Programmer
I am writing a security audit program that extracts a list of users and all projects to which they have been granted access (and the rights they have been granted).
I managed to do this with the API, but the (C#) code is basically thus:
The problem we found going live is, not only is it horribly inefficient (30 minutes on a 6GB database with exclusive access), it doesn't work (17 hours on the same 6GB database when it's in use, and over 6 hours (we killed the process before completion) on their new >10GB database).
In searching for a better solution, I found the ssusers tool from ezds.com that not only does exactly what I need, but it does it in a couple seconds. Only problem is, it's not licensed for use in a commercial environment (aside from the annoyance of having to parse its output into a database). So, basically, I want to do what it does.
As far as I can tell by playing around with it, it goes directly to SourceSafe's data files (names.dat, rights.dat, and um.dat in particular) and parses them to get the users and their access (and then goes into the alphabet directories to get the real project names). But I've been unable to find any documentation on how those files are layed out or how to break them down. I'm stuck.
I managed to do this with the API, but the (C#) code is basically thus:
Code:
[green]//vss is the opened VSSDatabase
//dt is the DataTable where I'm storing data[/green]
VSSItem root = vss.get_VSSItem("$/", false);
addVssRights(vss, root, dt);
private void addVssRights(VSSDatabase vssDb, VSSItem project, DataTable results) {
[tab]foreach (VSSUser user in vssDb.Users) {
[tab][tab]int rights = user.get_ProjectRights(project.Spec);
[tab][tab]if ((rights & (int)VSSRights.VSSRIGHTS_INHERITED) == 0) {
[tab][tab][tab]DataRow newRow = results.NewRow();
[tab][tab][tab]newRow["UserName"] = user.Name;
[tab][tab][tab]newRow["Project"] = project.Spec;
[tab][tab][tab]newRow["Rights"] = user.ReadOnly? "RO" : VssRightsToString(rights); [green]//convert rights to a string like "R C", "R C A", etc.[/green]
[tab][tab][tab]newRow.Table.Rows.Add(newRow);
[tab][tab]}
[tab]}
[tab]foreach (VSSItem item in project.get_Items(false)) {
[tab][tab]if (item.Type == (int)VSSItemType.VSSITEM_PROJECT)
[tab][tab][tab]addVssRights(vssDb, item, results);
[tab]}
}
It's horribly inefficient, but as far as I can tell through the methods exposed in the API, it's the only way to get all users' granted rights in all projects.In a nutshell said:Start with $/, loop through all users and see what rights have been granted to that project (not inherited).
Loop through all (not-deleted) children. For each child that is a project, loop through all users and see what rights have been granted to that project.
Repeat.
The problem we found going live is, not only is it horribly inefficient (30 minutes on a 6GB database with exclusive access), it doesn't work (17 hours on the same 6GB database when it's in use, and over 6 hours (we killed the process before completion) on their new >10GB database).
In searching for a better solution, I found the ssusers tool from ezds.com that not only does exactly what I need, but it does it in a couple seconds. Only problem is, it's not licensed for use in a commercial environment (aside from the annoyance of having to parse its output into a database). So, basically, I want to do what it does.
As far as I can tell by playing around with it, it goes directly to SourceSafe's data files (names.dat, rights.dat, and um.dat in particular) and parses them to get the users and their access (and then goes into the alphabet directories to get the real project names). But I've been unable to find any documentation on how those files are layed out or how to break them down. I'm stuck.