goactive-directoryldapldap-query

Go/Ldap get primary groups of a user


I'm using go/ldap to query my active directory to get all the groups of a specific user, the function is working but is not returning the Primary Groups, like Domain Users.

Code example

package main
import (
   "encoding/json"
   "errors"
   "fmt"
   "github.com/go-ldap/ldap/v3"
   "github.com/techoner/gophp"
   "handlers"
   "log"
   "reflect"
   "strconv"
   "strings"
)

func main(){
      conn, err := connect(bindServer,BindPort)
      if err != nil {
         log.Printf("Failed to connect to AD/LDAP with error: %s", err)
         return nil, fmt.Errorf("Failed to connect to AD/LDAP with error: %s", err)
      }
      errBind := conn.Bind(bindUser, bindPWD)
      if errBind != nil {
         if isLdapDebug {
            log.Printf("Failed to bind to AD/LDAP with error: %s", errBind)
         }
         return nil, fmt.Errorf("Failed to bind to AD/LDAP with error: %s", errBind)
      }


      searchRequest := ldap.NewSearchRequest(
         DC=domain,DC=local,
         ldap.ScopeWholeSubtree, ldap.NeverDerefAliases, 0, 0, false,
         fmt.Sprintf("(&(objectClass=user)(sAMAccountName=%s))", administrator),
         []string{"dn"},
         nil,
      )

      sr, err := conn.Search(searchRequest)

      if err != nil {
         return nil, err
      }

      if len(sr.Entries) != 1 {
         return nil, errors.New("User does not exist")
      }

      userdn := sr.Entries[0].DN
      log.Printf("USER DN IS =%s", userdn)
      searchRequest = ldap.NewSearchRequest(
         DC=domain,DC=local,
         ldap.ScopeWholeSubtree, ldap.NeverDerefAliases, 0, 0, false,
         fmt.Sprintf("(&(objectClass=group)(member=CN=Administrator,CN=Users,DC=domain,DC=local))"),
         []string{"cn"}, // can it be something else than "cn"?
         nil,
      )
      sr, err = conn.Search(searchRequest)
      if err != nil {
         return nil, err
      }
      
      groups := []string{}
      for _, entry := range sr.Entries {
         //fmt.Printf("%s", entry)
         groups = append(groups, entry.GetAttributeValue("cn"))
      }

      return groups, nil

}

Output

[Administrators Schema Admins Enterprise Admins Domain Admins Group Policy Creator Owners gteste1 gtest2]

The groups are correcly returned but is missing the primary groups.

Any way to return all groups of a specific user including Primary Groups?


Solution

  • To find the primary group in go using the lib

    github.com/go-ldap/ldap/v3
    

    I had to use this code sample:

    userdn := sr.Entries[0].DN
    groups := []string{}
    searchRequest = ldap.NewSearchRequest(
       data.Record.LdapSuffix,
       ldap.ScopeWholeSubtree, ldap.NeverDerefAliases, 0, SearchTimelimit, false,
       fmt.Sprintf("(&(objectCategory=person)(objectClass=user)(primaryGroupID=513)(sAMAccountName=%s))", ldap.EscapeFilter(username)),
       []string{"primaryGroupID"}, 
       nil,
    )
    sr, err = conn.Search(searchRequest)
    if err != nil {
       continue
    }
    
    if len(sr.Entries) > 0 {
       primaryGroup := sr.Entries[0].GetAttributeValue("primaryGroupID")
       if primaryGroup == "513" {
          if searchGroup == "Domain Users" {
             return true
          }
       }
    }