0

I would like to know if it is possible to read a certain string of n-length, from x character to y character without having to split it into smaller pieces.

I have the following string, for a path in AD CN=someName,OU=someGroup,OU=groups,DC=some,DC=domain,DC=com, and I would like to be able to just read the someName part of it, without splitting by = or , first. How do I achieve that?

Reason is, that I do not have to do group comparison as I am doing it right now:

SearchResult t1 = search.FindOne();
foreach (string s in t1.Properties["memberof"])
{
    foreach (string g in groups)
    {
        if (s.ToLower().Contains(g.ToLower()))
        {
            // do something
        }
    }
}

I would rather make the if clause to equals, but I do not want to always split the above path/groups into an array twice. How do I do that?

EInherjar
  • 339
  • 6
  • 17
  • 2
    _"I do not have to do group comparison"_ I dont get it, what is `groups`? – Tim Schmelter Jun 06 '17 at 07:51
  • @TimSchmelter I am comparing if a certain user is in a certain group, to check for rights, `groups` is an array of groups that are valid. Also, as I said, I would like to avoid using arrays if possible, and I'm relatively new to programming, so I do not know all the syntax, for example LINQ, etc... – EInherjar Jun 06 '17 at 07:53

4 Answers4

4

Using simple string manipulation with IndexOf and Substring:

string s = "CN=someName,OU=someGroup,OU=groups,DC=some,DC=domain,DC=com";

const string prefix = "CN=";
int start = s.IndexOf(prefix);
if (start >= 0)
{
    string value = s.Substring(start + prefix.Length, s.IndexOf(',', start) - prefix.Length);
    Console.WriteLine(value);
}

Note that this simple example would fail if the CN= entry was the last in the line (since it’s not terminated by a comma). You could check that first by looking at the return value of the second IndexOf call though.

But in this case, CN= will usually be the first thing anyway.

poke
  • 369,085
  • 72
  • 557
  • 602
1

If you are doing group comparisons I would use System.DirectoryServices.AccountManagement namespace

PrincipalContext Context = new PrincipalContext(ContextType.Domain, "");
UserPrincipal Usr = UserPrincipal.FindByIdentity(Context, "User");
GroupPrincipal G = GroupPrincipal.FindByIdentity(Context, "Group");

if(Usr.IsMemberOf(G)) {

}
David Lindon
  • 305
  • 2
  • 8
  • This would work, but it breaks if there are groups in the array of allowed groups, which do not exist in the AD yet. Any way to circumvent this? – EInherjar Jun 06 '17 at 08:54
0

With Split you can check if any of the given keys equals to the search value.

var val = "CN=someName,OU=someGroup,OU=groups,DC=some,DC=domain,DC=com";
var prefix = "CN";
var searchValue = "someName";
var contains = val.Split(',').Any(value => value.Split('=')[0] == prefix && value.Split('=')[1] == searchValue);

Insead of checking if the value is equal to the search value you can also just return the value.

var val = "CN=someName,OU=someGroup,OU=groups,DC=some,DC=domain,DC=com";
var prefix = "CN";
var foundValue = val.Split(',').FirstOrDefault(value => value.Split('=')[0] == prefix)?.Split('=')[1];

I still used Split despite you said you don't want to use it as I think it makes a nice one liner.

NtFreX
  • 10,379
  • 2
  • 43
  • 63
0

You can use String.IndexOf to find the correct offset, then use String.SubString to read the part you want.

const string input = "CN=someName,OU=someGroup,OU=groups,DC=some,DC=domain,DC=com";
const string start = "CN=";
const string stop = ",";

int startIndex = input.IndexOf(start, 0);
int stopIndex = input.IndexOf(stop, startIndex);

var extracted = input.Substring(startIndex + start.Length, stopIndex - startIndex - start.Length);

Console.WriteLine(extracted);

.net Fiddle

PS: maybe also take a look at Is there a .NET class that can parse CN= strings out of LDAP? for your special usecase!

Georg Patscheider
  • 9,357
  • 1
  • 26
  • 36