1 package ldap
2
3 import (
4 "context"
5 "crypto/tls"
6 "crypto/x509"
7 "fmt"
8 "io/ioutil"
9 "log"
10 "time"
11 )
12
13
14
15 func ExampleConn_Bind() {
16 l, err := DialURL("ldap://ldap.example.com:389")
17 if err != nil {
18 log.Fatal(err)
19 }
20 defer l.Close()
21
22 err = l.Bind("cn=read-only-admin,dc=example,dc=com", "password")
23 if err != nil {
24 log.Fatal(err)
25 }
26 }
27
28
29 func ExampleConn_Search() {
30 l, err := DialURL("ldap://ldap.example.com:389")
31 if err != nil {
32 log.Fatal(err)
33 }
34 defer l.Close()
35
36 searchRequest := NewSearchRequest(
37 "dc=example,dc=com",
38 ScopeWholeSubtree, NeverDerefAliases, 0, 0, false,
39 "(&(objectClass=organizationalPerson))",
40 []string{"dn", "cn"},
41 nil,
42 )
43
44 sr, err := l.Search(searchRequest)
45 if err != nil {
46 log.Fatal(err)
47 }
48
49 for _, entry := range sr.Entries {
50 fmt.Printf("%s: %v\n", entry.DN, entry.GetAttributeValue("cn"))
51 }
52 }
53
54
55 func ExampleConn_SearchAsync() {
56 l, err := DialURL(fmt.Sprintf("%s:%d", "ldap.example.com", 389))
57 if err != nil {
58 log.Fatal(err)
59 }
60 defer l.Close()
61
62 searchRequest := NewSearchRequest(
63 "dc=example,dc=com",
64 ScopeWholeSubtree, NeverDerefAliases, 0, 0, false,
65 "(&(objectClass=organizationalPerson))",
66 []string{"dn", "cn"},
67 nil,
68 )
69
70 ctx, cancel := context.WithCancel(context.Background())
71 defer cancel()
72
73 r := l.SearchAsync(ctx, searchRequest, 64)
74 for r.Next() {
75 entry := r.Entry()
76 fmt.Printf("%s has DN %s\n", entry.GetAttributeValue("cn"), entry.DN)
77 }
78 if err := r.Err(); err != nil {
79 log.Fatal(err)
80 }
81 }
82
83
84 func ExampleConn_Syncrepl() {
85 l, err := DialURL(fmt.Sprintf("%s:%d", "ldap.example.com", 389))
86 if err != nil {
87 log.Fatal(err)
88 }
89 defer l.Close()
90
91 searchRequest := NewSearchRequest(
92 "dc=example,dc=com",
93 ScopeWholeSubtree, NeverDerefAliases, 0, 0, false,
94 "(&(objectClass=organizationalPerson))",
95 []string{"dn", "cn"},
96 nil,
97 )
98
99 ctx, cancel := context.WithCancel(context.Background())
100 defer cancel()
101
102 mode := SyncRequestModeRefreshAndPersist
103 var cookie []byte = nil
104 r := l.Syncrepl(ctx, searchRequest, 64, mode, cookie, false)
105 for r.Next() {
106 entry := r.Entry()
107 if entry != nil {
108 fmt.Printf("%s has DN %s\n", entry.GetAttributeValue("cn"), entry.DN)
109 }
110 controls := r.Controls()
111 if len(controls) != 0 {
112 fmt.Printf("%s", controls)
113 }
114 }
115 if err := r.Err(); err != nil {
116 log.Fatal(err)
117 }
118 }
119
120
121 func ExampleConn_StartTLS() {
122 l, err := DialURL("ldap://ldap.example.com:389")
123 if err != nil {
124 log.Fatal(err)
125 }
126 defer l.Close()
127
128
129 err = l.StartTLS(&tls.Config{InsecureSkipVerify: true})
130 if err != nil {
131 log.Fatal(err)
132 }
133
134
135 }
136
137
138 func ExampleConn_Compare() {
139 l, err := DialURL("ldap://ldap.example.com:389")
140 if err != nil {
141 log.Fatal(err)
142 }
143 defer l.Close()
144
145 matched, err := l.Compare("cn=user,dc=example,dc=com", "uid", "someuserid")
146 if err != nil {
147 log.Fatal(err)
148 }
149
150 fmt.Println(matched)
151 }
152
153 func ExampleConn_PasswordModify_admin() {
154 l, err := DialURL("ldap://ldap.example.com:389")
155 if err != nil {
156 log.Fatal(err)
157 }
158 defer l.Close()
159
160 err = l.Bind("cn=admin,dc=example,dc=com", "password")
161 if err != nil {
162 log.Fatal(err)
163 }
164
165 passwordModifyRequest := NewPasswordModifyRequest("cn=user,dc=example,dc=com", "", "NewPassword")
166 _, err = l.PasswordModify(passwordModifyRequest)
167
168 if err != nil {
169 log.Fatalf("Password could not be changed: %s", err.Error())
170 }
171 }
172
173 func ExampleConn_PasswordModify_generatedPassword() {
174 l, err := DialURL("ldap://ldap.example.com:389")
175 if err != nil {
176 log.Fatal(err)
177 }
178 defer l.Close()
179
180 err = l.Bind("cn=user,dc=example,dc=com", "password")
181 if err != nil {
182 log.Fatal(err)
183 }
184
185 passwordModifyRequest := NewPasswordModifyRequest("", "OldPassword", "")
186 passwordModifyResponse, err := l.PasswordModify(passwordModifyRequest)
187 if err != nil {
188 log.Fatalf("Password could not be changed: %s", err.Error())
189 }
190
191 generatedPassword := passwordModifyResponse.GeneratedPassword
192 log.Printf("Generated password: %s\n", generatedPassword)
193 }
194
195 func ExampleConn_PasswordModify_setNewPassword() {
196 l, err := DialURL("ldap://ldap.example.com:389")
197 if err != nil {
198 log.Fatal(err)
199 }
200 defer l.Close()
201
202 err = l.Bind("cn=user,dc=example,dc=com", "password")
203 if err != nil {
204 log.Fatal(err)
205 }
206
207 passwordModifyRequest := NewPasswordModifyRequest("", "OldPassword", "NewPassword")
208 _, err = l.PasswordModify(passwordModifyRequest)
209
210 if err != nil {
211 log.Fatalf("Password could not be changed: %s", err.Error())
212 }
213 }
214
215 func ExampleConn_Modify() {
216 l, err := DialURL("ldap://ldap.example.com:389")
217 if err != nil {
218 log.Fatal(err)
219 }
220 defer l.Close()
221
222
223 modify := NewModifyRequest("cn=user,dc=example,dc=com", nil)
224 modify.Add("description", []string{"An example user"})
225 modify.Replace("mail", []string{"user@example.org"})
226
227 err = l.Modify(modify)
228 if err != nil {
229 log.Fatal(err)
230 }
231 }
232
233
234
235 func Example_userAuthentication() {
236
237 username := "someuser"
238 password := "userpassword"
239
240 bindusername := "readonly"
241 bindpassword := "password"
242
243 l, err := DialURL("ldap://ldap.example.com:389")
244 if err != nil {
245 log.Fatal(err)
246 }
247 defer l.Close()
248
249
250 err = l.StartTLS(&tls.Config{InsecureSkipVerify: true})
251 if err != nil {
252 log.Fatal(err)
253 }
254
255
256 err = l.Bind(bindusername, bindpassword)
257 if err != nil {
258 log.Fatal(err)
259 }
260
261
262 searchRequest := NewSearchRequest(
263 "dc=example,dc=com",
264 ScopeWholeSubtree, NeverDerefAliases, 0, 0, false,
265 fmt.Sprintf("(&(objectClass=organizationalPerson)(uid=%s))", EscapeFilter(username)),
266 []string{"dn"},
267 nil,
268 )
269
270 sr, err := l.Search(searchRequest)
271 if err != nil {
272 log.Fatal(err)
273 }
274
275 if len(sr.Entries) != 1 {
276 log.Fatal("User does not exist or too many entries returned")
277 }
278
279 userdn := sr.Entries[0].DN
280
281
282 err = l.Bind(userdn, password)
283 if err != nil {
284 log.Fatal(err)
285 }
286
287
288 err = l.Bind(bindusername, bindpassword)
289 if err != nil {
290 log.Fatal(err)
291 }
292 }
293
294 func Example_beherappolicy() {
295 l, err := DialURL("ldap://ldap.example.com:389")
296 if err != nil {
297 log.Fatal(err)
298 }
299 defer l.Close()
300
301 controls := []Control{}
302 controls = append(controls, NewControlBeheraPasswordPolicy())
303 bindRequest := NewSimpleBindRequest("cn=admin,dc=example,dc=com", "password", controls)
304
305 r, err := l.SimpleBind(bindRequest)
306 ppolicyControl := FindControl(r.Controls, ControlTypeBeheraPasswordPolicy)
307
308 var ppolicy *ControlBeheraPasswordPolicy
309 if ppolicyControl != nil {
310 ppolicy = ppolicyControl.(*ControlBeheraPasswordPolicy)
311 } else {
312 log.Printf("ppolicyControl response not available.\n")
313 }
314 if err != nil {
315 errStr := "ERROR: Cannot bind: " + err.Error()
316 if ppolicy != nil && ppolicy.Error >= 0 {
317 errStr += ":" + ppolicy.ErrorString
318 }
319 log.Print(errStr)
320 } else {
321 logStr := "Login Ok"
322 if ppolicy != nil {
323 if ppolicy.Expire >= 0 {
324 logStr += fmt.Sprintf(". Password expires in %d seconds\n", ppolicy.Expire)
325 } else if ppolicy.Grace >= 0 {
326 logStr += fmt.Sprintf(". Password expired, %d grace logins remain\n", ppolicy.Grace)
327 }
328 }
329 log.Print(logStr)
330 }
331 }
332
333 func Example_vchuppolicy() {
334 l, err := DialURL("ldap://ldap.example.com:389")
335 if err != nil {
336 log.Fatal(err)
337 }
338 defer l.Close()
339 l.Debug = true
340
341 bindRequest := NewSimpleBindRequest("cn=admin,dc=example,dc=com", "password", nil)
342
343 r, err := l.SimpleBind(bindRequest)
344
345 passwordMustChangeControl := FindControl(r.Controls, ControlTypeVChuPasswordMustChange)
346 var passwordMustChange *ControlVChuPasswordMustChange
347 if passwordMustChangeControl != nil {
348 passwordMustChange = passwordMustChangeControl.(*ControlVChuPasswordMustChange)
349 }
350
351 if passwordMustChange != nil && passwordMustChange.MustChange {
352 log.Printf("Password Must be changed.\n")
353 }
354
355 passwordWarningControl := FindControl(r.Controls, ControlTypeVChuPasswordWarning)
356
357 var passwordWarning *ControlVChuPasswordWarning
358 if passwordWarningControl != nil {
359 passwordWarning = passwordWarningControl.(*ControlVChuPasswordWarning)
360 } else {
361 log.Printf("ppolicyControl response not available.\n")
362 }
363 if err != nil {
364 log.Print("ERROR: Cannot bind: " + err.Error())
365 } else {
366 logStr := "Login Ok"
367 if passwordWarning != nil {
368 if passwordWarning.Expire >= 0 {
369 logStr += fmt.Sprintf(". Password expires in %d seconds\n", passwordWarning.Expire)
370 }
371 }
372 log.Print(logStr)
373 }
374 }
375
376
377
378 func ExampleControlPaging_manualPaging() {
379 conn, err := DialURL("ldap://ldap.example.com:389")
380 if err != nil {
381 log.Fatal(err)
382 }
383 defer conn.Close()
384
385 var pageSize uint32 = 32
386 searchBase := "dc=example,dc=com"
387 filter := "(objectClass=group)"
388 pagingControl := NewControlPaging(pageSize)
389 attributes := []string{}
390 controls := []Control{pagingControl}
391
392 for {
393 request := NewSearchRequest(searchBase, ScopeWholeSubtree, DerefAlways, 0, 0, false, filter, attributes, controls)
394 response, err := conn.Search(request)
395 if err != nil {
396 log.Fatalf("Failed to execute search request: %s", err.Error())
397 }
398
399
400
401
402
403
404 updatedControl := FindControl(response.Controls, ControlTypePaging)
405 if ctrl, ok := updatedControl.(*ControlPaging); ctrl != nil && ok && len(ctrl.Cookie) != 0 {
406 pagingControl.SetCookie(ctrl.Cookie)
407 continue
408 }
409
410
411 break
412 }
413 }
414
415
416
417 func ExampleConn_DirSync() {
418 conn, err := Dial("tcp", "ad.example.org:389")
419 if err != nil {
420 log.Fatalf("Failed to connect: %s\n", err)
421 }
422 defer conn.Close()
423
424 _, err = conn.SimpleBind(&SimpleBindRequest{
425 Username: "cn=Some User,ou=people,dc=example,dc=org",
426 Password: "MySecretPass",
427 })
428 if err != nil {
429 log.Fatalf("failed to bind: %s", err)
430 }
431
432 req := &SearchRequest{
433 BaseDN: `DC=example,DC=org`,
434 Filter: `(&(objectClass=person)(!(objectClass=computer)))`,
435 Attributes: []string{"*"},
436 Scope: ScopeWholeSubtree,
437 }
438
439 doMore := true
440 var cookie []byte
441 for doMore {
442 res, err := conn.DirSync(req, DirSyncObjectSecurity, 1000, cookie)
443 if err != nil {
444 log.Fatalf("failed to search: %s", err)
445 }
446 for _, entry := range res.Entries {
447 entry.Print()
448 }
449 ctrl := FindControl(res.Controls, ControlTypeDirSync)
450 if ctrl == nil || ctrl.(*ControlDirSync).Flags == 0 {
451 doMore = false
452 }
453 cookie = ctrl.(*ControlDirSync).Cookie
454 }
455
456
457 for {
458 res, err := conn.DirSync(req, DirSyncObjectSecurity, 1000, cookie)
459 if err != nil {
460 log.Fatalf("failed to search: %s", err)
461 }
462 for _, entry := range res.Entries {
463 entry.Print()
464 }
465 time.Sleep(15 * time.Second)
466 }
467 }
468
469
470 func ExampleConn_DirSyncAsync() {
471 conn, err := Dial("tcp", "ad.example.org:389")
472 if err != nil {
473 log.Fatalf("Failed to connect: %s\n", err)
474 }
475 defer conn.Close()
476
477 _, err = conn.SimpleBind(&SimpleBindRequest{
478 Username: "cn=Some User,ou=people,dc=example,dc=org",
479 Password: "MySecretPass",
480 })
481 if err != nil {
482 log.Fatalf("failed to bind: %s", err)
483 }
484
485 req := &SearchRequest{
486 BaseDN: `DC=example,DC=org`,
487 Filter: `(&(objectClass=person)(!(objectClass=computer)))`,
488 Attributes: []string{"*"},
489 Scope: ScopeWholeSubtree,
490 }
491
492 ctx, cancel := context.WithCancel(context.Background())
493 defer cancel()
494
495 var cookie []byte = nil
496 r := conn.DirSyncAsync(ctx, req, 64, DirSyncObjectSecurity, 1000, cookie)
497 for r.Next() {
498 entry := r.Entry()
499 if entry != nil {
500 entry.Print()
501 }
502 controls := r.Controls()
503 if len(controls) != 0 {
504 fmt.Printf("%s", controls)
505 }
506 }
507 if err := r.Err(); err != nil {
508 log.Fatal(err)
509 }
510 }
511
512
513 func ExampleConn_ExternalBind() {
514 ldapCert := "/path/to/cert.pem"
515 ldapKey := "/path/to/key.pem"
516 ldapCAchain := "/path/to/ca_chain.pem"
517
518
519 cert, err := tls.LoadX509KeyPair(ldapCert, ldapKey)
520 if err != nil {
521 log.Fatal(err)
522 }
523
524
525 caCert, err := ioutil.ReadFile(ldapCAchain)
526 if err != nil {
527 log.Fatal(err)
528 }
529 caCertPool := x509.NewCertPool()
530 caCertPool.AppendCertsFromPEM(caCert)
531
532
533 tlsConfig := &tls.Config{
534 Certificates: []tls.Certificate{cert},
535 RootCAs: caCertPool,
536 InsecureSkipVerify: true,
537 }
538
539
540 l, err := DialURL("ldap://ldap.example.com:389")
541 if err != nil {
542 log.Fatal(err)
543 }
544 defer l.Close()
545
546
547 err = l.StartTLS(tlsConfig)
548 if err != nil {
549 log.Fatal(err)
550 }
551
552
553 err = l.ExternalBind()
554 if err != nil {
555 log.Fatal(err)
556 }
557
558
559 }
560
561
562 func ExampleConn_WhoAmI() {
563 conn, err := DialURL("ldap.example.org:389")
564 if err != nil {
565 log.Fatalf("Failed to connect: %s\n", err)
566 }
567
568 _, err = conn.SimpleBind(&SimpleBindRequest{
569 Username: "uid=someone,ou=people,dc=example,dc=org",
570 Password: "MySecretPass",
571 })
572 if err != nil {
573 log.Fatalf("Failed to bind: %s\n", err)
574 }
575
576 res, err := conn.WhoAmI(nil)
577 if err != nil {
578 log.Fatalf("Failed to call WhoAmI(): %s\n", err)
579 }
580 fmt.Printf("I am: %s\n", res.AuthzID)
581 }
582
View as plain text