2019-05-17 19:57:26 +08:00 
										
									 
								 
							 
							
								
							 
							
								 
							 
							
							
								package  multildap 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								import  ( 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
									"errors" 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
									"github.com/grafana/grafana/pkg/models" 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
									"github.com/grafana/grafana/pkg/services/ldap" 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								// GetConfig gets LDAP config
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								var  GetConfig  =  ldap . GetConfig 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								// IsEnabled checks if LDAP is enabled
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								var  IsEnabled  =  ldap . IsEnabled 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2019-06-19 21:46:04 +08:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
								// newLDAP return instance of the single LDAP server
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								var  newLDAP  =  ldap . New 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2019-05-17 19:57:26 +08:00 
										
									 
								 
							 
							
								
							 
							
								 
							 
							
							
								// ErrInvalidCredentials is returned if username and password do not match
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								var  ErrInvalidCredentials  =  ldap . ErrInvalidCredentials 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2019-08-19 05:52:32 +08:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
								// ErrCouldNotFindUser is returned when username hasn't been found (not username+password)
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								var  ErrCouldNotFindUser  =  ldap . ErrCouldNotFindUser 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2019-05-17 19:57:26 +08:00 
										
									 
								 
							 
							
								
							 
							
								 
							 
							
							
								// ErrNoLDAPServers is returned when there is no LDAP servers specified
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								var  ErrNoLDAPServers  =  errors . New ( "No LDAP servers are configured" ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								// ErrDidNotFindUser if request for user is unsuccessful
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								var  ErrDidNotFindUser  =  errors . New ( "Did not find a user" ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								// IMultiLDAP is interface for MultiLDAP
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								type  IMultiLDAP  interface  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
									Login ( query  * models . LoginUserQuery )  ( 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
										* models . ExternalUserInfo ,  error , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
									) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
									Users ( logins  [ ] string )  ( 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
										[ ] * models . ExternalUserInfo ,  error , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
									) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
									User ( login  string )  ( 
							 
						 
					
						
							
								
									
										
										
										
											2019-09-04 01:34:44 +08:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
										* models . ExternalUserInfo ,  ldap . ServerConfig ,  error , 
							 
						 
					
						
							
								
									
										
										
										
											2019-05-17 19:57:26 +08:00 
										
									 
								 
							 
							
								
							 
							
								 
							 
							
							
									) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								// MultiLDAP is basic struct of LDAP authorization
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								type  MultiLDAP  struct  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
									configs  [ ] * ldap . ServerConfig 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								// New creates the new LDAP auth
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								func  New ( configs  [ ] * ldap . ServerConfig )  IMultiLDAP  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
									return  & MultiLDAP { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
										configs :  configs , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
									} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								// Login tries to log in the user in multiples LDAP
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								func  ( multiples  * MultiLDAP )  Login ( query  * models . LoginUserQuery )  ( 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
									* models . ExternalUserInfo ,  error , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								)  { 
							 
						 
					
						
							
								
									
										
										
										
											2019-06-07 20:16:00 +08:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2019-05-17 19:57:26 +08:00 
										
									 
								 
							 
							
								
							 
							
								 
							 
							
							
									if  len ( multiples . configs )  ==  0  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
										return  nil ,  ErrNoLDAPServers 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
									} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
									for  _ ,  config  :=  range  multiples . configs  { 
							 
						 
					
						
							
								
									
										
										
										
											2019-06-07 20:16:00 +08:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
										server  :=  newLDAP ( config ) 
							 
						 
					
						
							
								
									
										
										
										
											2019-05-17 19:57:26 +08:00 
										
									 
								 
							 
							
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
										if  err  :=  server . Dial ( ) ;  err  !=  nil  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
											return  nil ,  err 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
										} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
										defer  server . Close ( ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
										user ,  err  :=  server . Login ( query ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
										if  user  !=  nil  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
											return  user ,  nil 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
										} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
										// Continue if we couldn't find the user
 
							 
						 
					
						
							
								
									
										
										
										
											2019-08-19 05:52:32 +08:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
										if  err  ==  ErrCouldNotFindUser  { 
							 
						 
					
						
							
								
									
										
										
										
											2019-05-17 19:57:26 +08:00 
										
									 
								 
							 
							
								
							 
							
								 
							 
							
							
											continue 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
										} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
										if  err  !=  nil  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
											return  nil ,  err 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
										} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
									} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
									// Return invalid credentials if we couldn't find the user anywhere
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
									return  nil ,  ErrInvalidCredentials 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2019-09-04 01:34:44 +08:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
								// User attempts to find an user by login/username by searching into all of the configured LDAP servers. Then, if the user is found it returns the user alongisde the server it was found.
 
							 
						 
					
						
							
								
									
										
										
										
											2019-05-17 19:57:26 +08:00 
										
									 
								 
							 
							
								
							 
							
								 
							 
							
							
								func  ( multiples  * MultiLDAP )  User ( login  string )  ( 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
									* models . ExternalUserInfo , 
							 
						 
					
						
							
								
									
										
										
										
											2019-09-04 01:34:44 +08:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
									ldap . ServerConfig , 
							 
						 
					
						
							
								
									
										
										
										
											2019-05-17 19:57:26 +08:00 
										
									 
								 
							 
							
								
							 
							
								 
							 
							
							
									error , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								)  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
									if  len ( multiples . configs )  ==  0  { 
							 
						 
					
						
							
								
									
										
										
										
											2019-09-04 01:34:44 +08:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
										return  nil ,  ldap . ServerConfig { } ,  ErrNoLDAPServers 
							 
						 
					
						
							
								
									
										
										
										
											2019-05-17 19:57:26 +08:00 
										
									 
								 
							 
							
								
							 
							
								 
							 
							
							
									} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
									search  :=  [ ] string { login } 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
									for  _ ,  config  :=  range  multiples . configs  { 
							 
						 
					
						
							
								
									
										
										
										
											2019-06-07 20:16:00 +08:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
										server  :=  newLDAP ( config ) 
							 
						 
					
						
							
								
									
										
										
										
											2019-05-17 19:57:26 +08:00 
										
									 
								 
							 
							
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
										if  err  :=  server . Dial ( ) ;  err  !=  nil  { 
							 
						 
					
						
							
								
									
										
										
										
											2019-09-04 01:34:44 +08:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
											return  nil ,  * config ,  err 
							 
						 
					
						
							
								
									
										
										
										
											2019-05-17 19:57:26 +08:00 
										
									 
								 
							 
							
								
							 
							
								 
							 
							
							
										} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
										defer  server . Close ( ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2019-07-10 18:25:21 +08:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
										if  err  :=  server . Bind ( ) ;  err  !=  nil  { 
							 
						 
					
						
							
								
									
										
										
										
											2019-09-04 01:34:44 +08:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
											return  nil ,  * config ,  err 
							 
						 
					
						
							
								
									
										
										
										
											2019-07-10 18:25:21 +08:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
										} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2019-05-17 19:57:26 +08:00 
										
									 
								 
							 
							
								
							 
							
								 
							 
							
							
										users ,  err  :=  server . Users ( search ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
										if  err  !=  nil  { 
							 
						 
					
						
							
								
									
										
										
										
											2019-09-04 01:34:44 +08:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
											return  nil ,  * config ,  err 
							 
						 
					
						
							
								
									
										
										
										
											2019-05-17 19:57:26 +08:00 
										
									 
								 
							 
							
								
							 
							
								 
							 
							
							
										} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
										if  len ( users )  !=  0  { 
							 
						 
					
						
							
								
									
										
										
										
											2019-09-04 01:34:44 +08:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
											return  users [ 0 ] ,  * config ,  nil 
							 
						 
					
						
							
								
									
										
										
										
											2019-05-17 19:57:26 +08:00 
										
									 
								 
							 
							
								
							 
							
								 
							 
							
							
										} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
									} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2019-09-04 01:34:44 +08:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
									return  nil ,  ldap . ServerConfig { } ,  ErrDidNotFindUser 
							 
						 
					
						
							
								
									
										
										
										
											2019-05-17 19:57:26 +08:00 
										
									 
								 
							 
							
								
							 
							
								 
							 
							
							
								} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								// Users gets users from multiple LDAP servers
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								func  ( multiples  * MultiLDAP )  Users ( logins  [ ] string )  ( 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
									[ ] * models . ExternalUserInfo , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
									error , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								)  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
									var  result  [ ] * models . ExternalUserInfo 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
									if  len ( multiples . configs )  ==  0  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
										return  nil ,  ErrNoLDAPServers 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
									} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
									for  _ ,  config  :=  range  multiples . configs  { 
							 
						 
					
						
							
								
									
										
										
										
											2019-06-07 20:16:00 +08:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
										server  :=  newLDAP ( config ) 
							 
						 
					
						
							
								
									
										
										
										
											2019-05-17 19:57:26 +08:00 
										
									 
								 
							 
							
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
										if  err  :=  server . Dial ( ) ;  err  !=  nil  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
											return  nil ,  err 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
										} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
										defer  server . Close ( ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2019-07-10 18:25:21 +08:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
										if  err  :=  server . Bind ( ) ;  err  !=  nil  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
											return  nil ,  err 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
										} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2019-05-17 19:57:26 +08:00 
										
									 
								 
							 
							
								
							 
							
								 
							 
							
							
										users ,  err  :=  server . Users ( logins ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
										if  err  !=  nil  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
											return  nil ,  err 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
										} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
										result  =  append ( result ,  users ... ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
									} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
									return  result ,  nil 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								}