Как преобразовать * ldap.Запись в объект массива

#go #active-directory #ldap

#Вперед #active-directory #ldap

Вопрос:

У меня есть следующий код, который выполняет базовый запрос:

 package main

import (
  "fmt"
  "gopkg.in/ldap.v3"
  "log"
)

func main(){
  //First off, we connect to the LDAP server
  ldapURL := "ldaps://test.io:636"
  l, err := ldap.DialURL(ldapURL)
  if err != nil {
          log.Fatal(err)
  }
  defer l.Close()

  //Now we bind to it with credentials.
  err = l.Bind("CN=ad_binder,CN=Users,DC=test,DC=io", "Password")
  if err != nil {
      log.Fatal(err)
  }

  //After we've binded, we now query the LDAP server.
  baseDN := "dc=test,dc=io"
  filter := "(objectclass=*)"

  // Creates search request for LDAP server.
  searchReq := ldap.NewSearchRequest(baseDN, ldap.ScopeWholeSubtree, 0, 0, 0, false, filter, []string{}, []ldap.Control{})

  // Gets the results of the search request.
  result, err := l.Search(searchReq)
  if err != nil {
          //return fmt.Errorf("failed to query LDAP: %w", err)
  }

  //Prints all the attributes per entry in the search result.
  for _, entry := range result.Entries {
    fmt.Printf("%Tn", entry)
    //entry.Print()
    fmt.Println()
  }
}
  

С помощью этого кода я могу сказать, что тип, к которому относится «запись», — это * ldap .Запись.

Тем не менее, я хотел бы перевести их в объекты массива, чтобы позже добавить в один массив для сравнения. По сути, создание массива всех записей LDAP в результате запроса.

Некоторые атрибуты также находятся в базе 64, так что это необходимо учитывать, поскольку сейчас они не выводятся должным образом с помощью entry.Печать().

Например, у меня есть objectsid, dnsrecord и ipsecdata, все из которых являются базовыми 64. Тогда я бы сделал

РЕДАКТИРОВАТЬ (18.11.2020):

 //If the current LDAP attribute is in base 64, make sure it's encoded to base 64 when adding to the array.
if(entry[i] == "objectguid"){
  new_array[] = base64_encode(entry[i])
  } elseif(entry[i] == "dnsrecord"){
    new_array[] = base64_encode(entry[i])
  } elseif(entry[i] == "ipsecdata"){
    new_array[] = base64_encode(entry[i])
  }
//Now for any attributes that aren't in base 64 originally, just add to the array as normal.
else{
new_array[] = entry[i]
}

  

В настоящее время, если я запрашиваю сервер LDAP прямо сейчас, вот запись, которую я получаю от go:

 DN: CN=Remote Desktop Users,CN=Builtin,DC=test,DC=io
objectClass: [top group]
cn: [Remote Desktop Users]
uSNCreated: [3571]
objectGUID: [??8:@?$??)B?]
objectSid: [  ]
uSNChanged: [8916]
  

objectGUID и objectSid должны иметь следующие значения при правильном кодировании:

             [objectguid] => 6wiJ9Tg6f0CqJIDbKUKrEA==
            [objectsid] => AQIAAAAAAAUgAAAAKwIAAA==
  

Итак, конечный результат в моем массиве должен иметь следующее:

 DN: CN=Remote Desktop Users,CN=Builtin,DC=test,DC=io
objectClass: [top group]
cn: [Remote Desktop Users]
uSNCreated: [3571]
objectguid : 6wiJ9Tg6f0CqJIDbKUKrEA==
objectsid : AQIAAAAAAAUgAAAAKwIAAA==
uSNChanged: [8916]
  

Ответ №1:

Поскольку записи могут иметь атрибуты с несколькими значениями, вы можете попробовать использовать доступный API, какой вызов метода удовлетворит ваши потребности. в худшем случае у вас будет внутренний цикл.

если я правильно понял, вы хотите определить значения base64 и решить, кодировать или декодировать их. благодаря пакету encoding / base64 мы можем легко это проверить.

 var ans []string
for _, entry := range result.Entries {
    v := entry.GetAttributeValue("objectguid")
    if !isBase64(v) {
        ans = append(ans, base64.StdEncoding.EncodeToString([]byte(v)))
        continue
    }

    ans = append(ans, v)
}

func isBase64(s string) bool {
    _, err := base64.StdEncoding.DecodeString(strings.TrimSpace(s))
    return err == nil
}
  

вы также можете перебирать атрибуты, чтобы идентифицировать их по имени

 for _, entry := range result.Entries {
    for _, attr := range entry.Attributes {
        switch attr.Name {
            case "objectguid":
                s, _ := base64.StdEncoding.DecodeString(attr.Values[0]) // make sure to iterate the values properly
                fmt.Println(string(s))
            case "dnsrecord":
                fmt.Println("dsn record")
    }
}
  

Комментарии:

1. Извините, я должен был уточнить. Например, у меня есть 16 атрибутов в одной записи LDAP. 3 из этих атрибутов находятся в base64 на сервере LDAP, поэтому мне нужно закодировать их обратно в base64 при добавлении в массив. Я отредактирую исходный вопрос.

2. @tobeydw все хорошо. Я думаю, что ответ по-прежнему дает достаточно информации для достижения этой цели, есть ли что-нибудь, чего там нет?