func main() { l, err := ldap.Dial("tcp", fmt.Sprintf("%s:%d", ldapServer, ldapPort)) if err != nil { log.Fatalf("ERROR: %s\n", err.Error()) } defer l.Close() // l.Debug = true err = l.Bind(user, passwd) if err != nil { log.Printf("ERROR: Cannot bind: %s\n", err.Error()) return } search := ldap.NewSearchRequest( baseDN, ldap.ScopeWholeSubtree, ldap.NeverDerefAliases, 0, 0, false, filter, Attributes, nil) sr, err := l.Search(search) if err != nil { log.Fatalf("ERROR: %s\n", err.Error()) return } log.Printf("Search: %s -> num of entries = %d\n", search.Filter, len(sr.Entries)) sr.PrettyPrint(0) }
func LookupUser(endpoint string, baseDn string, userId string) (*api.User, error) { start := time.Now() l, err := ldap.DialTimeout("tcp", endpoint, time.Second*10) if err != nil { log.Printf("ERROR: %s\n", err.Error()) return nil, err } defer l.Close() // l.Debug = true //err = l.Bind(user, passwd) //if err != nil { // log.Printf("ERROR: Cannot bind: %s\n", err.Error()) // return //} search := ldap.NewSearchRequest( baseDn, ldap.ScopeWholeSubtree, ldap.NeverDerefAliases, 0, 0, false, fmt.Sprintf("(userId=%s)", userId), Attributes, nil) sr, err := l.Search(search) if err != nil { log.Printf("ERROR: %s\n", err.Error()) return nil, err } if len(sr.Entries) == 1 { log.Printf("Lookup %s OK\t%s", userId, time.Since(start)) return &api.User{ UserId: userId, DisplayName: sr.Entries[0].GetAttributeValue("displayName"), FirstName: sr.Entries[0].GetAttributeValue("givenName"), Initials: sr.Entries[0].GetAttributeValue("initials"), LastName: sr.Entries[0].GetAttributeValue("sn"), Description: sr.Entries[0].GetAttributeValue("description"), Department: sr.Entries[0].GetAttributeValue("uvaDisplayDepartment"), Title: sr.Entries[0].GetAttributeValue("title"), Office: sr.Entries[0].GetAttributeValue("physicalDeliveryOfficeName"), Phone: sr.Entries[0].GetAttributeValue("telephoneNumber"), Email: sr.Entries[0].GetAttributeValue("mail"), }, nil } log.Printf("Lookup %s NOT FOUND\t%s", userId, time.Since(start)) // return empty user if not found return nil, nil }
func ldap_grub_users() (map[string][]string, bool) { var m = map[string][]string{} var autoriz = true var ldapServer = "10.4.122.6" var ldapPort = uint16(389) var baseDN = "dc=mrg022,dc=mrg" var filter = []string{ "(&(cn=*)(mail=*arg.nrg.org.ru*)(userPrincipalName=*mrg022*)(userAccountControl=512))"} var attributes = []string{ "homeDirectory", "mail", "userPrincipalName"} l, err_ := ldap.Dial("tcp", fmt.Sprintf("%s:%d", ldapServer, ldapPort)) bind_ := l.Bind("ldap", "ldapldap") if bind_ != nil { autoriz = false } if err_ != nil { println(err_.Error()) //return err_.Error() } defer l.Close() searchRequest := ldap.NewSearchRequest( baseDN, ldap.ScopeWholeSubtree, ldap.DerefAlways, 0, 0, false, filter[0], attributes, nil) sr, err__ := l.Search(searchRequest) if err__ != nil { println(err__.Error()) } else { for i := 0; i < len(sr.Entries); i++ { if Replace(sr.Entries[i].GetAttributeValue("homeDirectory"), " ", "", 100) != "" { var mas = []string{} mas = append(mas, sr.Entries[i].GetAttributeValue("homeDirectory")) mas = append(mas, sr.Entries[i].GetAttributeValue("mail")) m[Replace(sr.Entries[i].GetAttributeValue("userPrincipalName"), "@mrg022.mrg", "", 1)] = mas } } } return m, autoriz }
/* Update() searches LDAP for the current user set that supports the necessary properties for Hologram. TODO: call this at some point during verification failure so that keys that have been recently added to LDAP work, instead of requiring a server restart. */ func (luc *ldapUserCache) Update() error { start := time.Now() filter := "(sshPublicKey=*)" searchRequest := ldap.NewSearchRequest( luc.baseDN, ldap.ScopeWholeSubtree, ldap.NeverDerefAliases, 0, 0, false, filter, []string{"sshPublicKey", luc.userAttr}, nil, ) searchResult, err := luc.server.Search(searchRequest) if err != nil { return err } for _, entry := range searchResult.Entries { username := entry.GetAttributeValue(luc.userAttr) userKeys := []ssh.PublicKey{} for _, eachKey := range entry.GetAttributeValues("sshPublicKey") { sshKeyBytes, _ := base64.StdEncoding.DecodeString(eachKey) userSSHKey, err := ssh.ParsePublicKey(sshKeyBytes) if err != nil { userSSHKey, _, _, _, err = ssh.ParseAuthorizedKey([]byte(eachKey)) if err != nil { log.Warning("SSH key parsing for user %s failed (key was '%s')! This key will not be added into LDAP.", username, eachKey) continue } } userKeys = append(userKeys, userSSHKey) } luc.users[username] = &User{ SSHKeys: userKeys, Username: username, } log.Debug("Information on %s (re-)generated.", username) } log.Debug("LDAP information re-cached.") luc.stats.Timing(1.0, "ldapCacheUpdate", time.Since(start)) return nil }
func (h ldapHandler) Search(boundDN string, searchReq ldap.SearchRequest, conn net.Conn) (ldap.ServerSearchResult, error) { s, err := h.getSession(conn) if err != nil { return ldap.ServerSearchResult{ResultCode: ldap.LDAPResultOperationsError}, nil } search := ldap.NewSearchRequest( searchReq.BaseDN, ldap.ScopeWholeSubtree, ldap.NeverDerefAliases, 0, 0, false, searchReq.Filter, searchReq.Attributes, nil) sr, err := s.ldap.Search(search) if err != nil { return ldap.ServerSearchResult{}, err } //log.Printf("P: Search OK: %s -> num of entries = %d\n", search.Filter, len(sr.Entries)) return ldap.ServerSearchResult{sr.Entries, []string{}, []ldap.Control{}, ldap.LDAPResultSuccess}, nil }
func search(l *ldap.Conn, filter string, attributes []string) (*ldap.Entry, *ldap.Error) { search := ldap.NewSearchRequest( BaseDN, ldap.ScopeWholeSubtree, ldap.NeverDerefAliases, 0, 0, false, filter, attributes, nil) sr, err := l.Search(search) if err != nil { log.Fatalf("ERROR: %s\n", err) return nil, err } log.Printf("Search: %s -> num of entries = %d\n", search.Filter, len(sr.Entries)) if len(sr.Entries) == 0 { return nil, ldap.NewError(ldap.ErrorDebugging, errors.New(fmt.Sprintf("no entries found for: %s", filter))) } return sr.Entries[0], nil }
func (h ldapHandler) Search(boundDN string, searchReq ldap.SearchRequest, conn net.Conn) (result ldap.ServerSearchResult, err error) { log.Debug("Search request as %s from %s for %s", boundDN, conn.RemoteAddr().String(), searchReq.Filter) stats_frontend.Add("search_reqs", 1) s, err := h.getSession(conn) if err != nil { stats_frontend.Add("search_ldapSession_errors", 1) return ldap.ServerSearchResult{ResultCode: ldap.LDAPResultOperationsError}, nil } search := ldap.NewSearchRequest( searchReq.BaseDN, searchReq.Scope, searchReq.DerefAliases, searchReq.SizeLimit, searchReq.TimeLimit, searchReq.TypesOnly, searchReq.Filter, searchReq.Attributes, searchReq.Controls, ) log.Debug("Search req to backend: %# v", pretty.Formatter(search)) sr, err := s.ldap.Search(search) log.Debug("Backend Search result: %# v", pretty.Formatter(sr)) ssr := ldap.ServerSearchResult{ Entries: sr.Entries, Referrals: sr.Referrals, Controls: sr.Controls, } log.Debug("Frontend Search result: %# v", pretty.Formatter(ssr)) if err != nil { e := err.(*ldap.Error) log.Debug("Search Err: %# v", pretty.Formatter(err)) stats_frontend.Add("search_errors", 1) ssr.ResultCode = ldap.LDAPResultCode(e.ResultCode) return ssr, err } stats_frontend.Add("search_successes", 1) log.Debug("AP: Search OK: %s -> num of entries = %d\n", search.Filter, len(ssr.Entries)) return ssr, nil }
func CheckUser(user User) (bool, error) { l, err := ldap.Dial("tcp", fmt.Sprintf("%s:%d", conf.LDAPServer, conf.LDAPPort)) if err != nil { return false, err } defer l.Close() err = l.Bind(conf.LDAPDomain+`\`+user.Name, user.Password) if err != nil { return false, err } filter := strings.Replace(conf.LDAPFilter, "@@SAMACCOUNTNAME@@", user.Name, -1) search := ldap.NewSearchRequest( conf.LDAPBaseDN, ldap.ScopeWholeSubtree, ldap.NeverDerefAliases, 0, 0, false, filter, []string{"memberof"}, nil) searchResult, err := l.Search(search) if len(searchResult.Entries) > 0 { return true, nil } return false, nil }
func main() { l, err := ldap.DialSSL("tcp", fmt.Sprintf("%s:%d", LdapServer, LdapPort), nil) if err != nil { log.Fatalf("ERROR: %s\n", err.String()) } defer l.Close() // l.Debug = true search := ldap.NewSearchRequest( BaseDN, ldap.ScopeWholeSubtree, ldap.NeverDerefAliases, 0, 0, false, Filter, Attributes, nil) sr, err := l.Search(search) if err != nil { log.Fatalf("ERROR: %s\n", err.String()) return } log.Printf("Search: %s -> num of entries = %d\n", search.Filter, len(sr.Entries)) sr.PrettyPrint(0) }
/* HandleServerRequest handles the flow for messages that this server accepts from clients. */ func (sm *server) HandleServerRequest(m protocol.MessageReadWriteCloser, r *protocol.ServerRequest) { if assumeRoleMsg := r.GetAssumeRole(); assumeRoleMsg != nil { log.Debug("Handling an assumeRole request.") sm.stats.Counter(1.0, "messages.assumeRole", 1) role := assumeRoleMsg.GetRole() user, err := sm.SSHChallenge(m) if err != nil { log.Errorf("Error trying to handle AssumeRole: %s", err.Error()) m.Close() return } if user != nil { creds, err := sm.credentials.AssumeRole(user, role, sm.enableLDAPRoles) if err != nil { // error message from Amazon, so forward that on to the client errStr := err.Error() errMsg := &protocol.Message{ Error: &errStr, } log.Errorf("Error from AWS for AssumeRole: %s", err.Error()) m.Write(errMsg) sm.stats.Counter(1.0, "errors.assumeRole", 1) //m.Close() return } m.Write(makeCredsResponse(creds)) return } } else if getUserCredentialsMsg := r.GetGetUserCredentials(); getUserCredentialsMsg != nil { sm.stats.Counter(1.0, "messages.getUserCredentialsMsg", 1) user, err := sm.SSHChallenge(m) if err != nil { log.Errorf("Error trying to handle GetUserCredentials: %s", err.Error()) m.Close() return } if user != nil { creds, err := sm.credentials.AssumeRole(user, sm.DefaultRole, sm.enableLDAPRoles) if err != nil { log.Errorf("Error trying to handle GetUserCredentials: %s", err.Error()) m.Close() return } m.Write(makeCredsResponse(creds)) return } } else if addSSHKeyMsg := r.GetAddSSHkey(); addSSHKeyMsg != nil { sm.stats.Counter(1.0, "messages.addSSHKeyMsg", 1) // Search for the user specified in this request. sr := ldap.NewSearchRequest( sm.baseDN, ldap.ScopeWholeSubtree, ldap.NeverDerefAliases, 0, 0, false, fmt.Sprintf("(%s=%s)", sm.userAttr, addSSHKeyMsg.GetUsername()), []string{"sshPublicKey", sm.userAttr, "userPassword"}, nil) user, err := sm.ldapServer.Search(sr) if err != nil { log.Errorf("Error trying to handle addSSHKeyMsg: %s", err.Error()) return } if len(user.Entries) == 0 { log.Errorf("User %s not found!", addSSHKeyMsg.GetUsername()) return } // Check their password. password := user.Entries[0].GetAttributeValue("userPassword") if password != addSSHKeyMsg.GetPasswordhash() { log.Errorf("Provided password for user %s does not match %s!", addSSHKeyMsg.GetUsername(), password) return } // Check to see if this SSH key already exists. for _, k := range user.Entries[0].GetAttributeValues("sshPublicKey") { if k == addSSHKeyMsg.GetSshkeybytes() { log.Warning("User %s already has this SSH key. Doing nothing.", addSSHKeyMsg.GetUsername()) successMsg := &protocol.Message{Success: &protocol.Success{}} m.Write(successMsg) return } } mr := ldap.NewModifyRequest(user.Entries[0].DN) mr.Add("sshPublicKey", []string{addSSHKeyMsg.GetSshkeybytes()}) err = sm.ldapServer.Modify(mr) if err != nil { log.Errorf("Could not modify LDAP user: %s", err.Error()) return } successMsg := &protocol.Message{Success: &protocol.Success{}} m.Write(successMsg) return } }
/* Update() searches LDAP for the current user set that supports the necessary properties for Hologram. TODO: call this at some point during verification failure so that keys that have been recently added to LDAP work, instead of requiring a server restart. */ func (luc *ldapUserCache) Update() error { start := time.Now() if luc.enableLDAPRoles { groupSearchRequest := ldap.NewSearchRequest( luc.baseDN, ldap.ScopeWholeSubtree, ldap.NeverDerefAliases, 0, 0, false, "(objectClass=groupOfNames)", []string{luc.roleAttribute}, nil, ) groupSearchResult, err := luc.server.Search(groupSearchRequest) if err != nil { return err } for _, entry := range groupSearchResult.Entries { dn := entry.DN arns := entry.GetAttributeValues(luc.roleAttribute) log.Debug("Adding %s to %s", arns, dn) luc.groups[dn] = arns } } filter := "(sshPublicKey=*)" searchRequest := ldap.NewSearchRequest( luc.baseDN, ldap.ScopeWholeSubtree, ldap.NeverDerefAliases, 0, 0, false, filter, []string{"sshPublicKey", luc.userAttr, "memberOf"}, nil, ) searchResult, err := luc.server.Search(searchRequest) if err != nil { return err } for _, entry := range searchResult.Entries { username := entry.GetAttributeValue(luc.userAttr) userKeys := []ssh.PublicKey{} for _, eachKey := range entry.GetAttributeValues("sshPublicKey") { sshKeyBytes, _ := base64.StdEncoding.DecodeString(eachKey) userSSHKey, err := ssh.ParsePublicKey(sshKeyBytes) if err != nil { userSSHKey, _, _, _, err = ssh.ParseAuthorizedKey([]byte(eachKey)) if err != nil { log.Warning("SSH key parsing for user %s failed (key was '%s')! This key will not be added into LDAP.", username, eachKey) continue } } userKeys = append(userKeys, userSSHKey) } arns := []string{} if luc.enableLDAPRoles { for _, groupDN := range entry.GetAttributeValues("memberOf") { log.Debug(groupDN) arns = append(arns, luc.groups[groupDN]...) } } luc.users[username] = &User{ SSHKeys: userKeys, Username: username, ARNs: arns, } log.Debug("Information on %s (re-)generated.", username) } log.Debug("LDAP information re-cached.") luc.stats.Timing(1.0, "ldapCacheUpdate", time.Since(start)) return nil }
func (o *opts) doquery(q query) (*ldap.SearchResult, error) { sr := &ldap.SearchResult{} // parse the ldap URL u, err := url.Parse(q.ldapURL) if err != nil { return sr, err } var port int if u.Scheme == "ldaps" { port = 636 } else if u.Scheme == "ldap" { port = 389 } else { return sr, fmt.Errorf("Unknown LDAP scheme: %s", u.Scheme) } parts := strings.Split(u.Host, ":") hostname := parts[0] if len(parts) > 1 { port, err = strconv.Atoi(parts[1]) if err != nil { return sr, err } } // connect to the ldap server var l *ldap.Conn if u.Scheme == "ldaps" { tlsConfig := tls.Config{} if o.goklp_insecure_skip_verify { tlsConfig.InsecureSkipVerify = true } l, err = ldap.DialTLS("tcp", fmt.Sprintf("%s:%d", hostname, port), &tlsConfig) if err != nil { return sr, err } } else if u.Scheme == "ldap" { l, err = ldap.Dial("tcp", fmt.Sprintf("%s:%d", hostname, port)) if err != nil { return sr, err } } defer l.Close() // do an ldap bind err = l.Bind(q.user, q.passwd) if err != nil { return sr, err } // do the ldap search search := ldap.NewSearchRequest( q.baseDN, ldap.ScopeWholeSubtree, ldap.NeverDerefAliases, 0, 0, false, q.filter, q.Attributes, nil) sr, err = l.Search(search) if err != nil { return sr, err } return sr, nil }