Minor stylistic changes
This commit is contained in:
parent
50233827b6
commit
ceee0bf2f4
3 changed files with 60 additions and 60 deletions
50
config.go
50
config.go
|
@ -13,11 +13,11 @@ type (
|
||||||
* */
|
* */
|
||||||
|
|
||||||
// LDAP server configuration
|
// LDAP server configuration
|
||||||
LdapConfig struct {
|
ldapConfig struct {
|
||||||
Host string
|
Host string `yaml:"host"`
|
||||||
Port uint16
|
Port uint16 `yaml:"port"`
|
||||||
Tls string
|
TLS string `yaml:"tls"`
|
||||||
TlsNoVerify bool `yaml:"tls_skip_verify"`
|
TLSNoVerify bool `yaml:"tls_skip_verify"`
|
||||||
CaChain string `yaml:"cachain"`
|
CaChain string `yaml:"cachain"`
|
||||||
BindUser string `yaml:"bind_user"`
|
BindUser string `yaml:"bind_user"`
|
||||||
BindPassword string `yaml:"bind_password"`
|
BindPassword string `yaml:"bind_password"`
|
||||||
|
@ -26,39 +26,39 @@ type (
|
||||||
}
|
}
|
||||||
|
|
||||||
// Graylog server configuration
|
// Graylog server configuration
|
||||||
GraylogConfig struct {
|
graylogConfig struct {
|
||||||
ApiBase string `yaml:"api_base"`
|
APIBase string `yaml:"api_base"`
|
||||||
Username string
|
Username string
|
||||||
Password string
|
Password string
|
||||||
DeleteAccounts bool `yaml:"delete_accounts"`
|
DeleteAccounts bool `yaml:"delete_accounts"`
|
||||||
}
|
}
|
||||||
|
|
||||||
// A Graylog object on which privileges are defined
|
// A Graylog object on which privileges are defined
|
||||||
GraylogObject struct {
|
graylogObject struct {
|
||||||
Type string
|
Type string `yaml:"type"`
|
||||||
Id string
|
ID string `yaml:"id"`
|
||||||
Level string
|
Level string `yaml:"level"`
|
||||||
}
|
}
|
||||||
|
|
||||||
// A mapping from a LDAP group to a set of privileges
|
// A mapping from a LDAP group to a set of privileges
|
||||||
GroupPrivileges struct {
|
groupPrivileges struct {
|
||||||
Roles []string
|
Roles []string
|
||||||
Privileges []GraylogObject
|
Privileges []graylogObject
|
||||||
}
|
}
|
||||||
|
|
||||||
// All group mappings
|
// All group mappings
|
||||||
GroupMapping map[string]GroupPrivileges
|
groupMapping map[string]groupPrivileges
|
||||||
|
|
||||||
// The whole configuration
|
// The whole configuration
|
||||||
Configuration struct {
|
configuration struct {
|
||||||
Ldap LdapConfig
|
LDAP ldapConfig
|
||||||
Graylog GraylogConfig
|
Graylog graylogConfig
|
||||||
Mapping GroupMapping
|
Mapping groupMapping
|
||||||
}
|
}
|
||||||
)
|
)
|
||||||
|
|
||||||
// Check group/privilege mapping configuration
|
// Check group/privilege mapping configuration
|
||||||
func checkPrivMapping(cfg GroupMapping, log *logrus.Entry) {
|
func checkPrivMapping(cfg groupMapping, log *logrus.Entry) {
|
||||||
for group, info := range cfg {
|
for group, info := range cfg {
|
||||||
log := log.WithField("group", group)
|
log := log.WithField("group", group)
|
||||||
for index, priv := range info.Privileges {
|
for index, priv := range info.Privileges {
|
||||||
|
@ -76,7 +76,7 @@ func checkPrivMapping(cfg GroupMapping, log *logrus.Entry) {
|
||||||
}
|
}
|
||||||
|
|
||||||
// Load and check the configuration file
|
// Load and check the configuration file
|
||||||
func loadConfiguration(flags cliFlags) (configuration Configuration) {
|
func loadConfiguration(flags cliFlags) (cfg configuration) {
|
||||||
log := log.WithField("config", flags.cfgFile)
|
log := log.WithField("config", flags.cfgFile)
|
||||||
log.Trace("Loading configuration")
|
log.Trace("Loading configuration")
|
||||||
cfgData, err := ioutil.ReadFile(flags.cfgFile)
|
cfgData, err := ioutil.ReadFile(flags.cfgFile)
|
||||||
|
@ -84,17 +84,17 @@ func loadConfiguration(flags cliFlags) (configuration Configuration) {
|
||||||
log.WithField("error", err).Fatal("Could not load configuration")
|
log.WithField("error", err).Fatal("Could not load configuration")
|
||||||
}
|
}
|
||||||
|
|
||||||
configuration = Configuration{
|
cfg = configuration{
|
||||||
Ldap: LdapConfig{
|
LDAP: ldapConfig{
|
||||||
Port: 389,
|
Port: 389,
|
||||||
Tls: "no",
|
TLS: "no",
|
||||||
},
|
},
|
||||||
}
|
}
|
||||||
err = yaml.Unmarshal(cfgData, &configuration)
|
err = yaml.Unmarshal(cfgData, &cfg)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
log.WithField("error", err).Fatal("Could not parse configuration")
|
log.WithField("error", err).Fatal("Could not parse configuration")
|
||||||
}
|
}
|
||||||
|
|
||||||
checkPrivMapping(configuration.Mapping, log)
|
checkPrivMapping(cfg.Mapping, log)
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
46
graylog.go
46
graylog.go
|
@ -13,15 +13,15 @@ import (
|
||||||
|
|
||||||
type (
|
type (
|
||||||
// A Graylog user and associated roles
|
// A Graylog user and associated roles
|
||||||
GraylogUser struct {
|
graylogUser struct {
|
||||||
Username string
|
Username string
|
||||||
Roles []string
|
Roles []string
|
||||||
}
|
}
|
||||||
|
|
||||||
// The response obtained when querying the Graylog server for a list of users.
|
// The response obtained when querying the Graylog server for a list of users.
|
||||||
GlUsers struct {
|
graylogUsers struct {
|
||||||
Users []struct {
|
Users []struct {
|
||||||
GraylogUser
|
graylogUser
|
||||||
External bool
|
External bool
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -53,16 +53,16 @@ var (
|
||||||
)
|
)
|
||||||
|
|
||||||
// Execute a Graylog API request, returning the status code and the body
|
// Execute a Graylog API request, returning the status code and the body
|
||||||
func executeApiCall(cfg GraylogConfig, method string, path string, data io.Reader) (status int, body []byte) {
|
func executeAPICall(cfg graylogConfig, method string, path string, data io.Reader) (status int, body []byte) {
|
||||||
log := log.WithFields(logrus.Fields{
|
log := log.WithFields(logrus.Fields{
|
||||||
"base": cfg.ApiBase,
|
"base": cfg.APIBase,
|
||||||
"username": cfg.Username,
|
"username": cfg.Username,
|
||||||
"method": method,
|
"method": method,
|
||||||
"path": path,
|
"path": path,
|
||||||
})
|
})
|
||||||
log.Trace("Executing Graylog API call")
|
log.Trace("Executing Graylog API call")
|
||||||
client := &http.Client{}
|
client := &http.Client{}
|
||||||
request, err := http.NewRequest(method, fmt.Sprintf("%s/%s", cfg.ApiBase, path), data)
|
request, err := http.NewRequest(method, fmt.Sprintf("%s/%s", cfg.APIBase, path), data)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
log.WithField("error", err).Fatal("Could not create HTTP request")
|
log.WithField("error", err).Fatal("Could not create HTTP request")
|
||||||
}
|
}
|
||||||
|
@ -86,22 +86,22 @@ func executeApiCall(cfg GraylogConfig, method string, path string, data io.Reade
|
||||||
}
|
}
|
||||||
|
|
||||||
// Get the list of Graylog users that have been imported from LDAP
|
// Get the list of Graylog users that have been imported from LDAP
|
||||||
func getGraylogUsers(configuration GraylogConfig) (users []GraylogUser) {
|
func getGraylogUsers(configuration graylogConfig) (users []graylogUser) {
|
||||||
log.Trace("Getting users from the Graylog API")
|
log.Trace("Getting users from the Graylog API")
|
||||||
status, body := executeApiCall(configuration, "GET", "users", nil)
|
status, body := executeAPICall(configuration, "GET", "users", nil)
|
||||||
if status != 200 {
|
if status != 200 {
|
||||||
log.WithField("status", status).Fatal("Could not read users")
|
log.WithField("status", status).Fatal("Could not read users")
|
||||||
}
|
}
|
||||||
|
|
||||||
data := GlUsers{}
|
data := graylogUsers{}
|
||||||
if err := json.Unmarshal(body, &data); err != nil {
|
if err := json.Unmarshal(body, &data); err != nil {
|
||||||
log.WithField("error", err).Fatal("Could not parse Graylog's user list")
|
log.WithField("error", err).Fatal("Could not parse Graylog's user list")
|
||||||
}
|
}
|
||||||
|
|
||||||
users = make([]GraylogUser, 0)
|
users = make([]graylogUser, 0)
|
||||||
for _, item := range data.Users {
|
for _, item := range data.Users {
|
||||||
if item.External {
|
if item.External {
|
||||||
users = append(users, item.GraylogUser)
|
users = append(users, item.graylogUser)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
log.WithField("users", len(users)).Info("Obtained users from the Graylog API")
|
log.WithField("users", len(users)).Info("Obtained users from the Graylog API")
|
||||||
|
@ -109,7 +109,7 @@ func getGraylogUsers(configuration GraylogConfig) (users []GraylogUser) {
|
||||||
}
|
}
|
||||||
|
|
||||||
// List groups an user is a member of.
|
// List groups an user is a member of.
|
||||||
func getUserGroups(user string, membership GroupMembers) (groups []string) {
|
func getUserGroups(user string, membership ldapGroupMembers) (groups []string) {
|
||||||
groups = make([]string, 0)
|
groups = make([]string, 0)
|
||||||
for group, members := range membership {
|
for group, members := range membership {
|
||||||
for _, member := range members {
|
for _, member := range members {
|
||||||
|
@ -123,7 +123,7 @@ func getUserGroups(user string, membership GroupMembers) (groups []string) {
|
||||||
}
|
}
|
||||||
|
|
||||||
// Compute roles that should apply to an user
|
// Compute roles that should apply to an user
|
||||||
func computeRoles(mapping GroupMapping, membership []string) (roles []string) {
|
func computeRoles(mapping groupMapping, membership []string) (roles []string) {
|
||||||
rset := make(map[string]bool)
|
rset := make(map[string]bool)
|
||||||
for _, group := range membership {
|
for _, group := range membership {
|
||||||
for _, role := range mapping[group].Roles {
|
for _, role := range mapping[group].Roles {
|
||||||
|
@ -141,7 +141,7 @@ func computeRoles(mapping GroupMapping, membership []string) (roles []string) {
|
||||||
}
|
}
|
||||||
|
|
||||||
// Compute privileges on Graylog objects that should be granted to an user
|
// Compute privileges on Graylog objects that should be granted to an user
|
||||||
func computePrivileges(mapping GroupMapping, membership []string) (privileges []string) {
|
func computePrivileges(mapping groupMapping, membership []string) (privileges []string) {
|
||||||
type privInfo struct {
|
type privInfo struct {
|
||||||
otp, oid string
|
otp, oid string
|
||||||
priv int
|
priv int
|
||||||
|
@ -149,7 +149,7 @@ func computePrivileges(mapping GroupMapping, membership []string) (privileges []
|
||||||
rset := make(map[string]privInfo)
|
rset := make(map[string]privInfo)
|
||||||
for _, group := range membership {
|
for _, group := range membership {
|
||||||
for _, priv := range mapping[group].Privileges {
|
for _, priv := range mapping[group].Privileges {
|
||||||
key := fmt.Sprintf("%s:%s", priv.Type, priv.Id)
|
key := fmt.Sprintf("%s:%s", priv.Type, priv.ID)
|
||||||
record, ok := rset[key]
|
record, ok := rset[key]
|
||||||
level := privLevels[priv.Level]
|
level := privLevels[priv.Level]
|
||||||
if ok && level <= record.priv {
|
if ok && level <= record.priv {
|
||||||
|
@ -157,7 +157,7 @@ func computePrivileges(mapping GroupMapping, membership []string) (privileges []
|
||||||
}
|
}
|
||||||
if !ok {
|
if !ok {
|
||||||
record.otp = priv.Type
|
record.otp = priv.Type
|
||||||
record.oid = priv.Id
|
record.oid = priv.ID
|
||||||
}
|
}
|
||||||
record.priv = level
|
record.priv = level
|
||||||
rset[key] = record
|
rset[key] = record
|
||||||
|
@ -176,10 +176,10 @@ func computePrivileges(mapping GroupMapping, membership []string) (privileges []
|
||||||
}
|
}
|
||||||
|
|
||||||
// Delete a Graylog user account
|
// Delete a Graylog user account
|
||||||
func deleteAccount(cfg GraylogConfig, user string) {
|
func deleteAccount(cfg graylogConfig, user string) {
|
||||||
log := log.WithField("user", user)
|
log := log.WithField("user", user)
|
||||||
log.Warning("Deleting Graylog account")
|
log.Warning("Deleting Graylog account")
|
||||||
code, body := executeApiCall(cfg, "DELETE", fmt.Sprintf("/users/%s", user), nil)
|
code, body := executeAPICall(cfg, "DELETE", fmt.Sprintf("/users/%s", user), nil)
|
||||||
if code != 204 {
|
if code != 204 {
|
||||||
log.WithFields(logrus.Fields{
|
log.WithFields(logrus.Fields{
|
||||||
"status": code,
|
"status": code,
|
||||||
|
@ -207,7 +207,7 @@ func getDifference(a []string, b []string) (diff []string) {
|
||||||
}
|
}
|
||||||
|
|
||||||
// Set an account's roles and grant it access to Graylog objects
|
// Set an account's roles and grant it access to Graylog objects
|
||||||
func setUserPrivileges(cfg GraylogConfig, user GraylogUser, roles []string, privileges []string) {
|
func setUserPrivileges(cfg graylogConfig, user graylogUser, roles []string, privileges []string) {
|
||||||
log := log.WithField("user", user.Username)
|
log := log.WithField("user", user.Username)
|
||||||
|
|
||||||
type perms struct {
|
type perms struct {
|
||||||
|
@ -219,7 +219,7 @@ func setUserPrivileges(cfg GraylogConfig, user GraylogUser, roles []string, priv
|
||||||
log.WithField("error", err).Fatal("Unable to generate permissions JSON")
|
log.WithField("error", err).Fatal("Unable to generate permissions JSON")
|
||||||
}
|
}
|
||||||
log.WithField("privileges", privileges).Info("Setting permissions")
|
log.WithField("privileges", privileges).Info("Setting permissions")
|
||||||
code, body := executeApiCall(cfg, "PUT",
|
code, body := executeAPICall(cfg, "PUT",
|
||||||
fmt.Sprintf("users/%s/permissions", user.Username),
|
fmt.Sprintf("users/%s/permissions", user.Username),
|
||||||
bytes.NewBuffer(data))
|
bytes.NewBuffer(data))
|
||||||
if code != 204 {
|
if code != 204 {
|
||||||
|
@ -233,7 +233,7 @@ func setUserPrivileges(cfg GraylogConfig, user GraylogUser, roles []string, priv
|
||||||
for _, role := range getDifference(roles, user.Roles) {
|
for _, role := range getDifference(roles, user.Roles) {
|
||||||
ep := fmt.Sprintf("roles/%s/members/%s", role, user.Username)
|
ep := fmt.Sprintf("roles/%s/members/%s", role, user.Username)
|
||||||
log.WithField("role", role).Info("Adding role")
|
log.WithField("role", role).Info("Adding role")
|
||||||
code, body := executeApiCall(cfg, "PUT", ep, placeholder)
|
code, body := executeAPICall(cfg, "PUT", ep, placeholder)
|
||||||
if code != 204 {
|
if code != 204 {
|
||||||
log.WithFields(logrus.Fields{
|
log.WithFields(logrus.Fields{
|
||||||
"status": code,
|
"status": code,
|
||||||
|
@ -245,7 +245,7 @@ func setUserPrivileges(cfg GraylogConfig, user GraylogUser, roles []string, priv
|
||||||
for _, role := range getDifference(user.Roles, roles) {
|
for _, role := range getDifference(user.Roles, roles) {
|
||||||
ep := fmt.Sprintf("roles/%s/members/%s", role, user.Username)
|
ep := fmt.Sprintf("roles/%s/members/%s", role, user.Username)
|
||||||
log.WithField("role", role).Info("Removing role")
|
log.WithField("role", role).Info("Removing role")
|
||||||
code, body := executeApiCall(cfg, "DELETE", ep, nil)
|
code, body := executeAPICall(cfg, "DELETE", ep, nil)
|
||||||
if code != 204 {
|
if code != 204 {
|
||||||
log.WithFields(logrus.Fields{
|
log.WithFields(logrus.Fields{
|
||||||
"status": code,
|
"status": code,
|
||||||
|
@ -257,7 +257,7 @@ func setUserPrivileges(cfg GraylogConfig, user GraylogUser, roles []string, priv
|
||||||
}
|
}
|
||||||
|
|
||||||
// Apply privilege mappings to the external Graylog users
|
// Apply privilege mappings to the external Graylog users
|
||||||
func applyMapping(cfg Configuration, users []GraylogUser, groups GroupMembers) {
|
func applyMapping(cfg configuration, users []graylogUser, groups ldapGroupMembers) {
|
||||||
for _, user := range users {
|
for _, user := range users {
|
||||||
log := log.WithField("user", user.Username)
|
log := log.WithField("user", user.Username)
|
||||||
membership := getUserGroups(user.Username, groups)
|
membership := getUserGroups(user.Username, groups)
|
||||||
|
|
24
ldap.go
24
ldap.go
|
@ -17,28 +17,28 @@ type (
|
||||||
ldapConn struct {
|
ldapConn struct {
|
||||||
conn *ldap.Conn
|
conn *ldap.Conn
|
||||||
log *logrus.Entry
|
log *logrus.Entry
|
||||||
cfg LdapConfig
|
cfg ldapConfig
|
||||||
usernames map[string]string
|
usernames map[string]string
|
||||||
counter uint
|
counter uint
|
||||||
}
|
}
|
||||||
|
|
||||||
// LDAP group members
|
// LDAP group members
|
||||||
GroupMembers map[string][]string
|
ldapGroupMembers map[string][]string
|
||||||
)
|
)
|
||||||
|
|
||||||
// Establish a connection to the LDAP server
|
// Establish a connection to the LDAP server
|
||||||
func getLdapConnection(cfg LdapConfig) *ldapConn {
|
func getLdapConnection(cfg ldapConfig) *ldapConn {
|
||||||
dest := fmt.Sprintf("%s:%d", cfg.Host, cfg.Port)
|
dest := fmt.Sprintf("%s:%d", cfg.Host, cfg.Port)
|
||||||
log := log.WithFields(logrus.Fields{
|
log := log.WithFields(logrus.Fields{
|
||||||
"ldap_server": dest,
|
"ldap_server": dest,
|
||||||
"ldap_tls": cfg.Tls,
|
"ldap_tls": cfg.TLS,
|
||||||
})
|
})
|
||||||
log.Trace("Establishing LDAP connection")
|
log.Trace("Establishing LDAP connection")
|
||||||
|
|
||||||
tlsConfig := &tls.Config{
|
tlsConfig := &tls.Config{
|
||||||
InsecureSkipVerify: cfg.TlsNoVerify,
|
InsecureSkipVerify: cfg.TLSNoVerify,
|
||||||
}
|
}
|
||||||
if cfg.Tls != "no" && cfg.CaChain != "" {
|
if cfg.TLS != "no" && cfg.CaChain != "" {
|
||||||
log := log.WithField("cachain", cfg.CaChain)
|
log := log.WithField("cachain", cfg.CaChain)
|
||||||
data, err := ioutil.ReadFile(cfg.CaChain)
|
data, err := ioutil.ReadFile(cfg.CaChain)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
|
@ -53,7 +53,7 @@ func getLdapConnection(cfg LdapConfig) *ldapConn {
|
||||||
|
|
||||||
var err error
|
var err error
|
||||||
var lc *ldap.Conn
|
var lc *ldap.Conn
|
||||||
if cfg.Tls == "yes" {
|
if cfg.TLS == "yes" {
|
||||||
lc, err = ldap.DialTLS("tcp", dest, tlsConfig)
|
lc, err = ldap.DialTLS("tcp", dest, tlsConfig)
|
||||||
} else {
|
} else {
|
||||||
lc, err = ldap.Dial("tcp", dest)
|
lc, err = ldap.Dial("tcp", dest)
|
||||||
|
@ -62,7 +62,7 @@ func getLdapConnection(cfg LdapConfig) *ldapConn {
|
||||||
log.WithField("error", err).Fatal("Failed to connect to the LDAP server")
|
log.WithField("error", err).Fatal("Failed to connect to the LDAP server")
|
||||||
}
|
}
|
||||||
|
|
||||||
if cfg.Tls == "starttls" {
|
if cfg.TLS == "starttls" {
|
||||||
err = lc.StartTLS(tlsConfig)
|
err = lc.StartTLS(tlsConfig)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
lc.Close()
|
lc.Close()
|
||||||
|
@ -201,11 +201,11 @@ func (conn *ldapConn) getGroupMembers(group string) (members []string) {
|
||||||
}
|
}
|
||||||
|
|
||||||
// Read the list of group members from the LDAP server for all groups in the mapping section.
|
// Read the list of group members from the LDAP server for all groups in the mapping section.
|
||||||
func readLdapGroups(configuration Configuration) GroupMembers {
|
func readLdapGroups(cfg configuration) ldapGroupMembers {
|
||||||
conn := getLdapConnection(configuration.Ldap)
|
conn := getLdapConnection(cfg.LDAP)
|
||||||
defer conn.close()
|
defer conn.close()
|
||||||
groups := make(GroupMembers)
|
groups := make(ldapGroupMembers)
|
||||||
for group := range configuration.Mapping {
|
for group := range cfg.Mapping {
|
||||||
groups[group] = conn.getGroupMembers(group)
|
groups[group] = conn.getGroupMembers(group)
|
||||||
}
|
}
|
||||||
return groups
|
return groups
|
||||||
|
|
Loading…
Reference in a new issue