Пример #1
0
func TestLocalSearch(t *testing.T) {
	fmt.Printf("TestLocalSearch: starting...\n")
	l := ldap.NewLDAPConnection(server, port)
	err := l.Connect()
	if err != nil {
		t.Error(err)
		return
	}
	defer l.Close()

	err = l.Bind(binddn, passwd)
	if err != nil {
		t.Error(err)
		return
	}

	search_request := ldap.NewSimpleSearchRequest(
		base_dn,
		ldap.ScopeWholeSubtree,
		filters[0],
		attributes,
	)

	sr, err := l.Search(search_request)
	if err != nil {
		t.Error(err)
		return
	}
	fmt.Printf("TestLocalSearch: %s -> num of entries = %d\n", search_request.Filter, len(sr.Entries))
}
Пример #2
0
func TestLocalMultiGoroutineSearch(t *testing.T) {
	fmt.Printf("TestLocalMultiGoroutineSearch: starting...\n")
	l := ldap.NewLDAPConnection(server, port)
	err := l.Connect()
	if err != nil {
		t.Error(err)
		return
	}
	defer l.Close()

	err = l.Bind(binddn, passwd)
	if err != nil {
		t.Error(err)
		return
	}

	results := make([]chan *ldap.SearchResult, len(filters))
	for i := range filters {
		results[i] = make(chan *ldap.SearchResult)
		go testLocalMultiGoroutineSearch(t, l, results[i], i)
	}
	for i := range filters {
		sr := <-results[i]
		if sr == nil {
			t.Errorf("Did not receive results from goroutine for %q", filters[i])
		} else {
			fmt.Printf("TestLocalMultiGoroutineSearch(%d): %s -> num of entries = %d\n", i, filters[i], len(sr.Entries))
		}
	}
}
Пример #3
0
func TestLocalAddAndDelete(t *testing.T) {
	fmt.Printf("TestLocalAddAndDelete: starting...\n")
	l := ldap.NewLDAPConnection(server, port)
	err := l.Connect()
	if err != nil {
		t.Error(err)
		return
	}
	defer l.Close()

	err = l.Bind(binddn, passwd)
	if err != nil {
		t.Error(err)
		return
	}

	addReq := ldap.NewAddRequest(addDNs[0])
	for _, attr := range addAttrs {
		addReq.AddAttribute(&attr)
	}
	fmt.Printf("Adding: %s\n", addDNs[0])
	err = l.Add(addReq)
	if err != nil {
		t.Errorf("Add : %s : %s\n", addDNs[0], err)
		return
	}
	fmt.Printf("Deleting: %s\n", addDNs[0])
	delRequest := ldap.NewDeleteRequest(addDNs[0])
	err = l.Delete(delRequest)
	if err != nil {
		t.Errorf("Delete : %s : %s\n", addDNs[0], err)
		return
	}
}
Пример #4
0
func (l *LDAPStorageHandler) Connect() bool {
	conn := ldap.NewLDAPConnection(l.LDAPServer, l.LDAPPort)
	if err := conn.Connect(); err != nil {
		log.Error("LDAP server connection failed: ", err)
		return false
	}
	log.Info("LDAP: Connection established")
	l.store = conn
	return true
}
Пример #5
0
func TestLocalConnect(t *testing.T) {
	fmt.Printf("TestLocalConnect: starting...\n")
	l := ldap.NewLDAPConnection(server, port)
	err := l.Connect()
	if err != nil {
		t.Error(err)
		return
	}
	defer l.Close()
	fmt.Printf("TestLocalConnect: finished...\n")
}
Пример #6
0
func TestLocalConnectTimeout(t *testing.T) {
	fmt.Printf("TestLocalConnectTimeout: starting...\n")
	fmt.Printf("Expecting a %v error\n", ldap.ErrorNetwork)
	l := ldap.NewLDAPConnection(server, port)
	l.NetworkConnectTimeout = 1 * time.Microsecond
	err := l.Connect()
	if err != nil {
		fmt.Print(err) // not an error
		return
	}
	defer l.Close()
	fmt.Print("TestLocalConnectTimeout: finished...\n")
}
Пример #7
0
func TestLocalSearchPagingWithHandler(t *testing.T) {
	fmt.Printf("TestLocalSearchPagingWithHandler: starting...\n")

	l := ldap.NewLDAPConnection(server, port)
	err := l.Connect()

	// l.Debug = true
	if err != nil {
		t.Error(err)
		return
	}
	defer l.Close()

	err = l.Bind(binddn, passwd)
	if err != nil {
		t.Error(err)
		return
	}
	search_request := ldap.NewSimpleSearchRequest(
		base_dn,
		ldap.ScopeWholeSubtree,
		filters[0],
		attributes,
	)

	l.Debug = false
	pagingControl := ldap.NewControlPaging(2)
	search_request.Controls = append(search_request.Controls, pagingControl)

	for {
		sr := new(ldap.SearchResult)
		err = l.SearchWithHandler(search_request, sr, nil)
		if err != nil {
			t.Error(err)
			return
		}
		_, pagingResponsePacket := ldap.FindControl(sr.Controls, ldap.ControlTypePaging)
		if pagingResponsePacket == nil {
			t.Errorf("Expected Paging Control.")
		}
		pagingControl.Cookie = pagingResponsePacket.(*ldap.ControlPaging).Cookie
		ldap.ReplaceControl(search_request.Controls, pagingControl)
		fmt.Printf("TestLocalSearchPagingWithHandler: %s entries = %d, Referrals = %d\n",
			search_request.Filter, len(sr.Entries), len(sr.Referrals))
		if len(pagingControl.Cookie) == 0 {
			return
		}
	}
}
Пример #8
0
func TestLocalOrderedSearch(t *testing.T) {
	fmt.Printf("TestLocalOrderedSearch: starting...\n")
	l := ldap.NewLDAPConnection(server, port)
	err := l.Connect()

	// l.Debug = true
	if err != nil {
		t.Error(err)
		return
	}
	defer l.Close()

	err = l.Bind(binddn, passwd)
	if err != nil {
		t.Error(err)
		return
	}
	search_request := ldap.NewSimpleSearchRequest(
		base_dn,
		ldap.ScopeWholeSubtree,
		filters[3],
		attributes,
	)

	serverSideSortAttrRuleOrder := ldap.ServerSideSortAttrRuleOrder{
		AttributeName: "cn",
		OrderingRule:  "",
		ReverseOrder:  false,
	}
	sortKeyList := make([]ldap.ServerSideSortAttrRuleOrder, 0, 1)
	sortKeyList = append(sortKeyList, serverSideSortAttrRuleOrder)
	sortControl := ldap.NewControlServerSideSortRequest(sortKeyList, true)
	fmt.Println(sortControl.String())
	search_request.AddControl(sortControl)
	l.Debug = false
	sr, err := l.Search(search_request)
	if err != nil {
		t.Error(err)
		return
	}
	_, sssResponse := ldap.FindControl(sr.Controls, ldap.ControlTypeServerSideSortResponse)
	if sssResponse != nil {
		fmt.Println(sssResponse.String())
	}
	fmt.Printf("TestLocalSearch: %s -> num of entries = %d\n", search_request.Filter, len(sr.Entries))
}
Пример #9
0
func backendAuthenticateLDAP(user, password string) bool {
	c := ldap.NewLDAPConnection(ldapServer, uint16(ldapPort))
	err := c.Connect()
	if err != nil {
		log.Println("ldap:", err)
		return false
	}

	err = c.Bind(fmt.Sprintf(ldapBind, user), password)
	if err != nil {
		log.Printf("ldap: %q: %s", user, err)
		return false
	}
	defer c.Close()

	return true
}
Пример #10
0
// Really just a test of setting the timeout.
func TestLocalBindWithTimeout(t *testing.T) {
	fmt.Printf("TestLocalBindWithTimeout: starting...\n")
	l := ldap.NewLDAPConnection(server, port)
	l.NetworkConnectTimeout = 5 * time.Second
	l.ReadTimeout = 5 * time.Second
	err := l.Connect()
	if err != nil {
		t.Error(err)
		return
	}
	defer l.Close()
	err = l.Bind(binddn, passwd)
	if err != nil {
		t.Error("Timed out in with a bind timeout of 5 seconds!")
		return
	}
	fmt.Printf("TestLocalBindWithTimeout: finished...\n")
}
Пример #11
0
func TestLocalBind(t *testing.T) {
	fmt.Printf("TestLocalBind: starting...\n")
	l := ldap.NewLDAPConnection(server, port)
	l.Debug = true
	l.NetworkConnectTimeout = 5 * time.Second
	err := l.Connect()
	if err != nil {
		t.Error(err)
		return
	}
	defer l.Close()
	err = l.Bind(binddn, passwd)
	if err != nil {
		t.Error(err)
		return
	}
	fmt.Printf("TestLocalBind: finished...\n")
}
Пример #12
0
func TestLocalVlvSearch(t *testing.T) {
	fmt.Printf("TestLocalVlvSearch: starting...\n")
	l := ldap.NewLDAPConnection(server, port)
	err := l.Connect()

	// l.Debug = true
	if err != nil {
		t.Error(err)
		return
	}
	defer l.Close()

	err = l.Bind(binddn, passwd)
	if err != nil {
		t.Error(err)
		return
	}
	search_request := ldap.NewSimpleSearchRequest(
		base_dn,
		ldap.ScopeWholeSubtree,
		"(cn=*)",
		attributes,
	)
	vlvControl := new(ldap.ControlVlvRequest)
	vlvControl.BeforeCount = 0
	vlvControl.AfterCount = 3

	offset := new(ldap.VlvOffSet)
	offset.Offset = 1
	offset.ContentCount = 3

	vlvControl.ByOffset = offset

	//pack, _ := vlvControl.Encode()
	//fmt.Println(hex.Dump(pack.Bytes()))

	search_request.AddControl(vlvControl)

	serverSideSortAttrRuleOrder := ldap.ServerSideSortAttrRuleOrder{
		AttributeName: "cn",
		OrderingRule:  "",
		ReverseOrder:  false,
	}
	sortKeyList := make([]ldap.ServerSideSortAttrRuleOrder, 0, 1)
	sortKeyList = append(sortKeyList, serverSideSortAttrRuleOrder)
	sortControl := ldap.NewControlServerSideSortRequest(sortKeyList, true)
	search_request.AddControl(sortControl)

	l.Debug = false
	sr, err := l.Search(search_request)
	if err != nil {
		t.Error(err)
		return
	}
	_, vlvResp := ldap.FindControl(sr.Controls, ldap.ControlTypeVlvResponse)
	if vlvResp != nil {
		fmt.Println(vlvResp.String())
	}
	for _, entry := range sr.Entries {
		fmt.Println(entry.GetAttributeValues("cn")[0])
	}
	fmt.Printf("TestLocalVlvSearch (byOffSet): %s -> num of entries = %d\n", search_request.Filter, len(sr.Entries))

	search_request = ldap.NewSimpleSearchRequest(
		base_dn,
		ldap.ScopeWholeSubtree,
		"(cn=*)",
		attributes,
	)

	vlvControl = new(ldap.ControlVlvRequest)
	vlvControl.BeforeCount = 0
	vlvControl.AfterCount = 3
	vlvControl.GreaterThanOrEqual = "Aaren Amar"

	//pack, _ := vlvControl.Encode()
	//fmt.Println(hex.Dump(pack.Bytes()))

	search_request.AddControl(vlvControl)
	search_request.AddControl(sortControl)

	sr, err = l.Search(search_request)
	if err != nil {
		t.Error(err)
		return
	}
	_, vlvResp = ldap.FindControl(sr.Controls, ldap.ControlTypeVlvResponse)
	if vlvResp != nil {
		fmt.Println(vlvResp.String())
	}
	for _, entry := range sr.Entries {
		fmt.Println(entry.GetAttributeValues("cn")[0])
	}
	fmt.Printf("TestLocalVlvSearch (value): %s -> num of entries = %d\n", search_request.Filter, len(sr.Entries))
	fmt.Printf("TestLocalVlvSearch: Finished.\n")
}
Пример #13
0
func TestLocalSearchWithHandler(t *testing.T) {
	fmt.Printf("TestLocalSearchWithHandler: starting...\n")

	l := ldap.NewLDAPConnection(server, port)
	err := l.Connect()

	// l.Debug = true
	if err != nil {
		t.Error(err)
		return
	}
	defer l.Close()

	err = l.Bind(binddn, passwd)
	if err != nil {
		t.Error(err)
		return
	}
	search_request := ldap.NewSimpleSearchRequest(
		base_dn,
		ldap.ScopeWholeSubtree,
		filters[0],
		attributes,
	)

	l.Debug = false

	// Blocking
	fmt.Println("Blocking version...")
	resultCounter := new(counter)
	err = l.SearchWithHandler(search_request, resultCounter, nil)
	if err != nil {
		t.Error(err)
		return
	}
	fmt.Printf("TestLocalSearchWithHandler: %s entries = %d, Referrals = %d\n",
		search_request.Filter, resultCounter.EntryCount, resultCounter.ReferenceCount)

	// Non-Blocking
	fmt.Println("Non-Blocking version...")
	resultChan := make(chan error)
	resultCounter = new(counter)
	go l.SearchWithHandler(search_request, resultCounter, resultChan)
	fmt.Println("do stuff ...")
	err = <-resultChan
	if err != nil {
		t.Error(err)
		return
	}
	fmt.Printf("TestLocalSearchWithHandler - go routine: %s entries = %d, Referrals = %d\n",
		search_request.Filter, resultCounter.EntryCount, resultCounter.ReferenceCount)

	// TODO blocking + abandon non-trival version.

	// Non-Blocking + Abandoning
	fmt.Println("Non-Blocking + Abandon version...")
	resultChan = make(chan error)
	resultCounter = new(counter)
	resultCounter.AbandonAtEntryCount = 4
	go l.SearchWithHandler(search_request, resultCounter, resultChan)
	err = <-resultChan
	if err != nil {
		t.Error(err)
		return
	}
	fmt.Printf("TestLocalSearchWithHandler - go routine: %s entries = %d, Referrals = %d\n",
		search_request.Filter, resultCounter.EntryCount, resultCounter.ReferenceCount)
}
Пример #14
0
func TestLocalControlMatchedValuesRequest(t *testing.T) {
	fmt.Printf("LocalControlMatchedValuesRequest: starting...\n")
	l := ldap.NewLDAPConnection(server, port)
	err := l.Connect()
	if err != nil {
		t.Error(err)
		return
	}
	defer l.Close()

	err = l.Bind(binddn, passwd)
	if err != nil {
		t.Error(err)
		return
	}

	addReq := ldap.NewAddRequest(addDNs[0])
	for _, attr := range addAttrs {
		addReq.AddAttribute(&attr)
	}
	fmt.Printf("Adding: %s\n", addDNs[0])
	err = l.Add(addReq)
	if err != nil {
		t.Errorf("Add : %s : %s\n", addDNs[0], err)
		return
	}

	fmt.Printf("Modify: %s = {aaa, bbb, ccc}\n", "description")
	mod := ldap.NewMod(ldap.ModAdd, "description", []string{"aaa", "bbb", "ccc", "aabb"})
	modreq := ldap.NewModifyRequest(addDNs[0])
	modreq.AddMod(mod)
	err = l.Modify(modreq)
	if err != nil {
		t.Errorf("Modify: %s : %s\n", addDNs[0], err)
		return
	}

	control := ldap.NewControlMatchedValuesRequest(true, "(description=aaa)")
	fmt.Println(control.String())
	fmt.Printf("Search: (objectclass=*), (description=aaa) via MatchedValuesRequest\n")
	search_request := ldap.NewSimpleSearchRequest(
		addDNs[0],
		ldap.ScopeBaseObject,
		"(objectclass=*)",
		[]string{"description"},
	)
	search_request.AddControl(control)
	//l.Debug = true
	sr, err := l.Search(search_request)
	if err != nil {
		t.Errorf("Search: %s : %s\n", addDNs[0], err)
		return
	}
	//l.Debug = false
	fmt.Println("Search Result:")
	fmt.Print(sr)

	control = ldap.NewControlMatchedValuesRequest(true, "(description=a*)")
	fmt.Println(control.String())
	fmt.Printf("Search: (objectclass=*), (description=a*) via MatchedValuesRequest\n")
	search_request = ldap.NewSimpleSearchRequest(
		addDNs[0],
		ldap.ScopeBaseObject,
		"(objectclass=*)",
		[]string{"description"},
	)
	search_request.AddControl(control)
	//l.Debug = true
	sr, err = l.Search(search_request)
	if err != nil {
		t.Errorf("Search: %s : %s\n", addDNs[0], err)
		return
	}
	//l.Debug = false
	fmt.Println("Search Result:")
	fmt.Print(sr)

	fmt.Printf("Deleting: %s\n", addDNs[0])
	delRequest := ldap.NewDeleteRequest(addDNs[0])
	err = l.Delete(delRequest)

	if err != nil {
		t.Errorf("Delete : %s : %s\n", addDNs[0], err)
		return
	}
}
Пример #15
0
func TestLocalCompare(t *testing.T) {
	fmt.Printf("TestLocalCompare: starting...\n")
	l := ldap.NewLDAPConnection(server, port)
	err := l.Connect()
	if err != nil {
		t.Error(err)
		return
	}
	defer l.Close()

	err = l.Bind(binddn, passwd)
	if err != nil {
		t.Error(err)
		return
	}

	addReq := ldap.NewAddRequest(addDNs[0])
	for _, attr := range addAttrs {
		addReq.AddAttribute(&attr)
	}
	fmt.Printf("Adding: %s\n", addDNs[0])
	err = l.Add(addReq)
	if err != nil {
		t.Errorf("Add : %s : %s\n", addDNs[0], err)
		return
	}

	fmt.Printf("Comparing: %s : sn=Boy which is True\n", addDNs[0])
	compareReq := ldap.NewCompareRequest(addDNs[0], "sn", "Boy")
	result, cerr := l.Compare(compareReq)
	if cerr != nil {
		t.Error(err)
		return
	}
	if result != true {
		t.Error("Compare Result should have been true")
		return
	}
	fmt.Printf("Compare Result : %v\n", result)

	fmt.Printf("Comparing: %s : sn=BoyIsThisWrong which is False\n", addDNs[0])
	compareReq = ldap.NewCompareRequest(addDNs[0], "sn", "BoyIsThisWrong")
	result, cerr = l.Compare(compareReq)
	if cerr != nil {
		t.Error(cerr)
		return
	}
	if result == true {
		t.Error("Compare Result should have been false")
		return
	}
	fmt.Printf("Compare Result : %v\n", result)

	fmt.Printf("Deleting: %s\n", addDNs[0])
	delRequest := ldap.NewDeleteRequest(addDNs[0])
	err = l.Delete(delRequest)
	if err != nil {
		t.Errorf("Delete : %s : %s\n", addDNs[0], err)
		return
	}
}
Пример #16
0
func TestLocalControlPermissiveModifyRequest(t *testing.T) {
	fmt.Printf("ControlPermissiveModifyRequest: starting...\n")
	l := ldap.NewLDAPConnection(server, port)
	err := l.Connect()
	if err != nil {
		t.Error(err)
		return
	}
	defer l.Close()

	err = l.Bind(binddn, passwd)
	if err != nil {
		t.Error(err)
		return
	}

	addReq := ldap.NewAddRequest(addDNs[0])
	for _, attr := range addAttrs {
		addReq.AddAttribute(&attr)
	}
	fmt.Printf("Adding: %s\n", addDNs[0])
	err = l.Add(addReq)
	if err != nil {
		t.Errorf("Add : %s : %s\n", addDNs[0], err)
		return
	}

	modreq := ldap.NewModifyRequest(addDNs[0])
	mod := ldap.NewMod(ldap.ModAdd, "description", []string{"aaa"})
	modreq.AddMod(mod)
	fmt.Println(modreq)
	err = l.Modify(modreq)
	if err != nil {
		t.Errorf("Modify : %s : %s\n", addDNs[0], err)
		return
	}

	mod = ldap.NewMod(ldap.ModAdd, "description", []string{"aaa", "bbb", "ccc"})
	modreq = ldap.NewModifyRequest(addDNs[0])
	modreq.AddMod(mod)
	control := ldap.NewControlString(ldap.ControlTypePermissiveModifyRequest, true, "")
	fmt.Println(control.String())
	modreq.AddControl(control)
	fmt.Println(modreq)
	err = l.Modify(modreq)
	if err != nil {
		t.Errorf("Modify (Permissive): %s : %s\n", addDNs[0], err)
		return
	}

	mod = ldap.NewMod(ldap.ModAdd, "description", []string{"aaa", "bbb", "ccc", "ddd"})
	modreq = ldap.NewModifyRequest(addDNs[0])
	modreq.AddMod(mod)
	control = ldap.NewControlPermissiveModifyRequest(false)
	fmt.Println(control.String())
	modreq.AddControl(control)
	fmt.Println(modreq)
	err = l.Modify(modreq)
	if err != nil {
		t.Errorf("Modify (Permissive): %s : %s\n", addDNs[0], err)
		return
	}

	fmt.Printf("Deleting: %s\n", addDNs[0])
	delRequest := ldap.NewDeleteRequest(addDNs[0])
	err = l.Delete(delRequest)

	if err != nil {
		t.Errorf("Delete : %s : %s\n", addDNs[0], err)
		return
	}
}
Пример #17
0
func LdapAuthenticator(options *LdapOptions) (martini.Handler, error) {
	hostInfo := HostExpr.FindStringSubmatch(options.Host)

	config := &ldapConfig{}
	switch hostInfo[1] {
	case "ldap":
		config.SSL = false
	case "ldaps":
		config.SSL = true
	default:
		return nil, fmt.Errorf("invalid ldap protocol: %s", hostInfo[1])
	}
	config.Host = hostInfo[2]

	if hostInfo[4] != "" {
		port, err := strconv.ParseUint(hostInfo[4], 10, 16)
		if err != nil {
			return nil, fmt.Errorf("unable to parse ldap port: %s", err)
		}
		config.Port = uint16(port)
	} else {
		if config.SSL {
			config.Port = 636
		} else {
			config.Port = 389
		}
	}

	return func(res http.ResponseWriter, req *http.Request, c martini.Context, log *log.Logger) {
		// HACK TODO: do not put routing logic in the auth handler
		// The /ping endpoint does not have auth, so explicitly exclude it here
		if req.URL.Path == "/ping" {
			return
		}

		authHandler := auth.BasicFunc(func(username, password string) bool {
			// create the ldap server connection
			var conn *ldap.LDAPConnection
			if config.SSL {
				tlsConfig := tls.Config{
					ServerName: config.Host,
				}
				conn = ldap.NewLDAPSSLConnection(config.Host, config.Port, &tlsConfig)
			} else {
				conn = ldap.NewLDAPConnection(config.Host, config.Port)
			}

			// attempt to connect to the ldap server
			if err := conn.Connect(); err != nil {
				log.Printf("Unable to connect to LDAP: %s", err)
				return false
			}

			// perform an anonymous search for the user's dn so we can attempt to bind as them
			req := ldap.SearchRequest{
				BaseDN: options.BaseDN,
				Filter: fmt.Sprintf(options.UserFilter, ldap.EscapeFilterValue(username)),
				Scope:  ldap.ScopeWholeSubtree,
			}
			res, err := conn.Search(&req)
			if err != nil {
				log.Printf("Error performing LDAP search: %s", err)
				return false
			}

			// Return false if the number of entries isn't exactly 1.  If multiple
			// results were returned, there is an ambiguity so return false instead
			// of proceeding. If no entries were returned, we have no idea who this
			// is and cannot authenticate.
			if len(res.Entries) != 1 {
				if len(res.Entries) > 1 {
					log.Printf("User '%s' attempted to authenticate but multiple entries exists", username)
				} else {
					log.Printf("User '%s' attempted to authenticate but does not exist", username)
				}
				return false
			}

			dn := res.Entries[0].DN
			if err := conn.Bind(dn, password); err != nil {
				log.Printf("User '%s' attempted to authenticate but provided an invalid password", username)
				return false
			}
			log.Printf("Authenticated successfully as %s", username)
			return true
		})
		authenticate := authHandler.(func(http.ResponseWriter, *http.Request, martini.Context))
		authenticate(res, req, c)
	}, nil
}