diff --git a/glauth/pkg/command/server.go b/glauth/pkg/command/server.go index 6c15b2670f..674b4c8fde 100644 --- a/glauth/pkg/command/server.go +++ b/glauth/pkg/command/server.go @@ -200,6 +200,7 @@ func Server(cfg *config.Config) *cli.Command { glauth.LDAPS(&lscfg), glauth.Backend(&bcfg), glauth.Fallback(&fcfg), + glauth.RoleBundleUUID(cfg.RoleBundleUUID), ) if err != nil { diff --git a/glauth/pkg/config/config.go b/glauth/pkg/config/config.go index 50f2c7d662..12576b75cc 100644 --- a/glauth/pkg/config/config.go +++ b/glauth/pkg/config/config.go @@ -58,16 +58,17 @@ type Backend struct { // Config combines all available configuration parts. type Config struct { - File string - Log Log - Debug Debug - HTTP HTTP - Tracing Tracing - Ldap Ldap - Ldaps Ldaps - Backend Backend - Fallback Backend - Version string + File string + Log Log + Debug Debug + HTTP HTTP + Tracing Tracing + Ldap Ldap + Ldaps Ldaps + Backend Backend + Fallback Backend + Version string + RoleBundleUUID string } // New initializes a new configuration with or without defaults. diff --git a/glauth/pkg/flagset/flagset.go b/glauth/pkg/flagset/flagset.go index 7d5cd079de..1bfeeb166e 100644 --- a/glauth/pkg/flagset/flagset.go +++ b/glauth/pkg/flagset/flagset.go @@ -115,6 +115,13 @@ func ServerWithConfig(cfg *config.Config) []cli.Flag { EnvVars: []string{"GLAUTH_DEBUG_ZPAGES"}, Destination: &cfg.Debug.Zpages, }, + &cli.StringFlag{ + Name: "role-bundle-id", + Value: "71881883-1768-46bd-a24d-a356a2afdf7f", // BundleUUIDRoleAdmin + Usage: "roleid used to make internal grpc requests", + EnvVars: []string{"GLAUTH_ROLE_BUNDLE_ID"}, + Destination: &cfg.RoleBundleUUID, + }, &cli.StringFlag{ Name: "ldap-addr", diff --git a/glauth/pkg/server/glauth/ocis.go b/glauth/pkg/server/glauth/ocis.go index 69409d8f40..d22d8b8080 100644 --- a/glauth/pkg/server/glauth/ocis.go +++ b/glauth/pkg/server/glauth/ocis.go @@ -2,6 +2,7 @@ package glauth import ( "context" + "encoding/json" "fmt" "net" "strconv" @@ -9,10 +10,12 @@ import ( "github.com/glauth/glauth/pkg/handler" "github.com/glauth/glauth/pkg/stats" + "github.com/micro/go-micro/v2/metadata" ber "github.com/nmcclain/asn1-ber" "github.com/nmcclain/ldap" accounts "github.com/owncloud/ocis/accounts/pkg/proto/v0" "github.com/owncloud/ocis/ocis-pkg/log" + "github.com/owncloud/ocis/ocis-pkg/middleware" ) type queryType string @@ -29,6 +32,7 @@ type ocisHandler struct { basedn string nameFormat string groupFormat string + rbid string } func (h ocisHandler) Bind(bindDN, bindSimplePw string, conn net.Conn) (ldap.LDAPResultCode, error) { @@ -66,8 +70,22 @@ func (h ocisHandler) Bind(bindDN, bindSimplePw string, conn net.Conn) (ldap.LDAP } userName := strings.TrimPrefix(parts[0], "cn=") + // TODO make glauth context aware + ctx := context.Background() + + // use a session with the bound user? + roleIDs, err := json.Marshal([]string{h.rbid}) + if err != nil { + h.log.Error(). + Err(err). + Str("handler", "ocis"). + Msg("could not marshal roleid json") + return ldap.LDAPResultOperationsError, nil + } + ctx = metadata.Set(ctx, middleware.RoleIDs, string(roleIDs)) + // check password - res, err := h.as.ListAccounts(context.TODO(), &accounts.ListAccountsRequest{ + res, err := h.as.ListAccounts(ctx, &accounts.ListAccountsRequest{ //Query: fmt.Sprintf("username eq '%s'", username), // TODO this allows lookung up users when you know the username using basic auth // adding the password to the query is an option but sending the sover the wira a la scim seems ugly @@ -76,6 +94,7 @@ func (h ocisHandler) Bind(bindDN, bindSimplePw string, conn net.Conn) (ldap.LDAP }) if err != nil || len(res.Accounts) == 0 { h.log.Error(). + Err(err). Str("handler", "ocis"). Str("username", userName). Str("binddn", bindDN). @@ -162,6 +181,22 @@ func (h ocisHandler) Search(bindDN string, searchReq ldap.SearchRequest, conn ne } } + // TODO make glauth context aware + ctx := context.Background() + + // use a session with the bound user? + roleIDs, err := json.Marshal([]string{h.rbid}) + if err != nil { + h.log.Error(). + Err(err). + Str("handler", "ocis"). + Msg("could not marshal roleid json") + return ldap.ServerSearchResult{ + ResultCode: ldap.LDAPResultOperationsError, + }, nil + } + ctx = metadata.Set(ctx, middleware.RoleIDs, string(roleIDs)) + entries := []*ldap.Entry{} h.log.Debug(). Str("handler", "ocis"). @@ -173,7 +208,7 @@ func (h ocisHandler) Search(bindDN string, searchReq ldap.SearchRequest, conn ne Msg("parsed query") switch qtype { case usersQuery: - accounts, err := h.as.ListAccounts(context.TODO(), &accounts.ListAccountsRequest{ + accounts, err := h.as.ListAccounts(ctx, &accounts.ListAccountsRequest{ Query: query, }) if err != nil { @@ -193,7 +228,7 @@ func (h ocisHandler) Search(bindDN string, searchReq ldap.SearchRequest, conn ne } entries = append(entries, h.mapAccounts(accounts.Accounts)...) case groupsQuery: - groups, err := h.gs.ListGroups(context.TODO(), &accounts.ListGroupsRequest{ + groups, err := h.gs.ListGroups(ctx, &accounts.ListGroupsRequest{ Query: query, }) if err != nil { @@ -501,6 +536,7 @@ func NewOCISHandler(opts ...Option) handler.Handler { basedn: options.BaseDN, nameFormat: options.NameFormat, groupFormat: options.GroupFormat, + rbid: options.RoleBundleUUID, } return handler } diff --git a/glauth/pkg/server/glauth/option.go b/glauth/pkg/server/glauth/option.go index b936f37ef0..025410e0ad 100644 --- a/glauth/pkg/server/glauth/option.go +++ b/glauth/pkg/server/glauth/option.go @@ -22,6 +22,7 @@ type Options struct { BaseDN string NameFormat string GroupFormat string + RoleBundleUUID string AccountsService accounts.AccountsService GroupsService accounts.GroupsService } @@ -113,3 +114,10 @@ func GroupsService(val accounts.GroupsService) Option { o.GroupsService = val } } + +// RoleBundleUUID provides a role bundle UUID to make internal grpc requests. +func RoleBundleUUID(val string) Option { + return func(o *Options) { + o.RoleBundleUUID = val + } +} diff --git a/glauth/pkg/server/glauth/server.go b/glauth/pkg/server/glauth/server.go index 3d9881daec..ccf8868eb1 100644 --- a/glauth/pkg/server/glauth/server.go +++ b/glauth/pkg/server/glauth/server.go @@ -78,6 +78,7 @@ func Server(opts ...Option) (*LdapSvc, error) { BaseDN(s.backend.Backend.BaseDN), NameFormat(s.backend.Backend.NameFormat), GroupFormat(s.backend.Backend.GroupFormat), + RoleBundleUUID(options.RoleBundleUUID), ) default: return nil, fmt.Errorf("unsupported backend %s - must be 'ldap', 'owncloud' or 'accounts'", s.backend.Backend.Datastore) @@ -115,6 +116,7 @@ func Server(opts ...Option) (*LdapSvc, error) { BaseDN(s.fallback.Backend.BaseDN), NameFormat(s.fallback.Backend.NameFormat), GroupFormat(s.fallback.Backend.GroupFormat), + RoleBundleUUID(options.RoleBundleUUID), ) default: return nil, fmt.Errorf("unsupported fallback %s - must be 'ldap', 'owncloud' or 'accounts'", s.fallback.Backend.Datastore)