-
Notifications
You must be signed in to change notification settings - Fork 6
/
Copy pathou.go
138 lines (106 loc) · 3.21 KB
/
ou.go
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
package goldap
import (
"fmt"
"github.com/go-ldap/ldap/v3"
)
// CreateOrganizationalUnit creates ldap OrganizationalUnit
func (c *Client) CreateOrganizationalUnit(dn, description, managedBy string) error {
req := ldap.NewAddRequest(dn, []ldap.Control{})
req.Attribute("objectClass", []string{"organizationalUnit"})
if description != "" {
req.Attribute("description", []string{description})
}
if managedBy != "" {
req.Attribute("managedBy", []string{managedBy})
}
return c.Conn.Add(req)
}
// SearchOUByName searches an LDAP OU by name and returns its DN
func (c *Client) SearchOUByName(name, ou string, scope int) (string, error) {
// Request name and description attributes
req := ldap.NewSearchRequest(
ou,
scope,
ldap.NeverDerefAliases,
0,
0,
false,
fmt.Sprintf("(&(objectClass=organizationalUnit)(ou=%s))", name),
[]string{},
[]ldap.Control{},
)
// Search for OU
sr, err := c.Conn.Search(req)
if err != nil {
return "", fmt.Errorf("searching OU by name: %s", err)
}
// If no entries found, OU doesn't exists, return error
if len(sr.Entries) == 0 {
return "", fmt.Errorf("OU %q not found in OU %q", name, ou)
}
// If more than one entry, it's an error
if len(sr.Entries) > 1 {
return "", fmt.Errorf("more than one OU found with name %q in OU %q", name, ou)
}
// Return OU DN
return sr.Entries[0].DN, nil
}
// ReadOrganizationalUnit reads an OrganizationalUnit
func (c *Client) ReadOrganizationalUnit(dn string) (entries map[string][]string, err error) {
filter := "(objectClass=organizationalUnit)"
req := ldap.NewSearchRequest(
dn,
ldap.ScopeBaseObject,
ldap.NeverDerefAliases,
0,
0,
false,
filter,
[]string{"*"},
[]ldap.Control{},
)
sr, err := c.Conn.Search(req)
if err != nil {
return nil, err
}
if len(sr.Entries) == 0 {
return nil, ldap.NewError(ldap.LDAPResultNoSuchObject, fmt.Errorf("the filter '%s' doesn't match any OU: %s", filter, dn))
}
if len(sr.Entries) > 1 {
return nil, ldap.NewError(ldap.LDAPResultOther, fmt.Errorf("the filter '%s' match more than one OU: %s", filter, dn))
}
entries = map[string][]string{}
for _, entry := range sr.Entries {
for _, attr := range entry.Attributes {
if !isExcludedAttribute(attr.Name) {
entries[attr.Name] = attr.Values
}
}
}
return entries, nil
}
// UpdateOrganizationalUnit updates ldap OrganizationalUnit description
func (c *Client) UpdateOrganizationalUnitDescription(dn string, description string) error {
req := ldap.NewModifyRequest(dn, []ldap.Control{})
if description == "" {
req.Delete("description", []string{})
} else {
req.Replace("description", []string{description})
}
return c.Conn.Modify(req)
}
// UpdateOrganizationalUnitManagedBy updates ldap OrganizationalUnit managedBy
func (c *Client) UpdateOrganizationalUnitManagedBy(dn string, managedBy string) error {
req := ldap.NewModifyRequest(dn, []ldap.Control{})
if managedBy == "" {
req.Delete("managedBy", []string{})
} else {
req.Replace("managedBy", []string{managedBy})
}
return c.Conn.Modify(req)
}
// DeleteOrganizationalUnit deletes the specify OrganizationalUnit
func (c *Client) DeleteOrganizationalUnit(dn string) error {
req := ldap.NewDelRequest(dn, []ldap.Control{})
return c.Conn.Del(req)
}