“This is the sixth day of my participation in the Gwen Challenge in November. Check out the details: The Last Gwen Challenge in 2021.”
When we work with other organizations, we may not be the party that builds the server, but the party that belongs to the client, and need to get the organizational structure of the server, according to certain conditions to get the data of the server, or it can be the synchronous organizational structure
While golang’s data structure is not as rich as c++, there are libraries that handle ldap
Pkg.go. dev/gopkg.in/ld…
We can also download the library on Github
go get github.com/go-ldap/ldap/v3
Copy the code
The latest Version of Golang for the LDAP library is Version: V3.1.0
Start coding
Let’s write a demo that captures the organizational structure of the LDAP server we set up last time
This is our simple LDAP server, you can use the LDAP Admin visual management tool to view the specific page effect
After we download the library, our coding idea is as follows:
- Enter the LDAP server address and administrator information to establish a connection to the LDAP server
- Write a query request and start querying the LDAP server
- Print out the query structure as provided by the LDAP V3 library
Connecting to the server
Func DialURL(addr String, opts… DialOpt) (*Conn, error) to establish a connection to the LDAP server
ml, err := ldap.DialURL("ldap://xxxx")
iferr ! =nil {
log.Fatal(err)
}
defer ml.Close()
Copy the code
We fill in the address, can not input port number, library function has been done for us, we can look at the source
The DialURL function is used to connect to the LDAP server and a successful connection will return us a new connection
We can continue to look at this function call c, err := dc.dial(u).
Golang’s library determines whether to perform encrypted or unencrypted transmission based on whether the address we enter is LDAP or LDAPS, which corresponds to port 389 for unencrypted access and port 636 for encrypted access
Add administrator binding information
The LDAP domain information is dc=xiaomotong,dc=com
My administrator is cn=admin,dc=xiaomotong,dc=com
_, err = ml.SimpleBind(&ldap.SimpleBindRequest{
Username: "cn=admin,dc=xiaomotong,dc=com",
Password: "123123",})iferr ! =nil {
log.Fatalf("Failed to bind: %s\n", err)
}
fmt.Println("connect successfully !!")
Copy the code
Take a look at the SimpleBindRequest data structure in action
// SimpleBindRequest represents a username/password bind operation
type SimpleBindRequest struct {
// Username is the name of the Directory object that the client wishes to bind as
Username string
// Password is the credentials to bind with
Password string
// Controls are optional controls to send with the bind request
Controls []Control
// AllowEmptyPassword sets whether the client allows binding with an empty password
// (normally used for unauthenticated bind).
AllowEmptyPassword bool
}
Copy the code
- Username
- Password
The domain user and password to be bound to the client
- Controls
The control that needs to bind the request
- AllowEmptyPassword
Whether to allow an empty password. If an empty password is used, an unauthorized user is bound
Write the query request and start querying the LDAP server
searchRequest := ldap.NewSearchRequest(
"dc=xiaomotong,dc=com",
ldap.ScopeWholeSubtree,
ldap.NeverDerefAliases,
0.0.false."(ou=People)"And []string{},
nil,
)
searchResult, err := ml.Search(searchRequest)
iferr ! =nil {
log.Println("can't search ", err.Error())
}
log.Printf("%d".len(searchResult.Entries))
Copy the code
Write a query request, that is, simply give our structure a negative operation, fill in the corresponding parameters, you can start the query, let’s take a look at the structure NewSearchRequest
Basically fill in the corresponding domain information
- BaseDN, a unique identifier for a domain
- Scope scope is selected by default
ScopeWholeSubtree
To query all subtrees - DerefAliases, SizeLimit, TimeLimit, TypesOnly Fill in the default value
- Filter, the Filter condition that the query needs, can write the condition according to our actual situation, just like the condition that writes the query database, cannot be empty here, otherwise the program will crash
F:\codegitee\golang_study\later_learning\ldap_test>go run main.go
connect successfully !!
2021/11/06 21:07:59 can't search LDAP Result Code 201 "Filter Compile Error": ldap: error parsing filter
panic: runtime error: invalid memory address or nil pointer dereference
[signal 0xc0000005 code=0x0 addr=0x4 pc=0xa33cef]
goroutine 1 [running]:
main.main()
F:/codegitee/golang_study/later_learning/ldap_test/main.go:40 +0x24f
exit status 2
Copy the code
- Attributes, which Attributes need to be returned, is a slice that will return all Attributes if we default to fill in the blank
View the source of the corresponding Search function
The general logic of the code is that doRequest sends the data group package to the LDAP server for a request, and when the request is successful, the data in response is parsed according to the different contents of the tag
Finally returns a pointer to the *SearchResult query result
Enter query information
for _, item := range searchResult.Entries {
item.Print()
fmt.Printf("\n\n")}Copy the code
In the source code above, we can see that the output query information is iterated through searchresult. Entries and we can see the corresponding data structure
We can see in the result that there is a single Entry []*Entry, which is a slice containing multiple * Entries. In ldap servers, one Entry represents a unique record
The Entry structure is the corresponding DN, the unique identification name of a record, and its related attributes
So in EntryAttribute structure, we can see that we have Name, we have Values, and this is the RDN that we talked about earlier, which is a key-value pair, multiple key-value pairs that form a DN
Finally, let’s see what happens
>go run main.go
connect successfully !!
2021/11/06 21:20:58 1
DN: ou=People,dc=xiaomotong,dc=com
objectClass: [organizationalUnit]
ou: [People]
Copy the code
The result is one message. Yes, since our ou=people has only one record, if we need to query the entire LDAP server, we can change the Filter position of the above code to objectClass=*
Explain the above results:
- DN represents a unique record and is used to identify the meaning of the name
- ObjectClass is a class. OrganizationalUnit represents an organization unit OU, which can be understood as a group
- Ou: [People] indicates that the name of the ou is People
Welcome to like, follow and favorites
Friends, your support and encouragement, I insist on sharing, improve the quality of the power
All right, that’s it for this time
Technology is open, our mentality, should be more open. Embrace change, live in the sun, and strive to move forward.
I am Nezha, welcome to like, see you next time ~