providers/ldap: Added auto-generated uidNumber and guidNumber generated attributes for use with SSSD and similar software. (#1138)
* Added auto-generated uidNumber and guidNumber generated attributes for use with SSSD and similar software. The starting number for uid/gid can be configured iva environtment variables and is by default 2000 which should work fine for most instances unless there are more than 999 local accounts on the server/computer. The uidNumber is just the users Pk + the starting number. The guidNumber is calculated by the last couple of bytes in the uuid of the group + the starting number, this should have a low enough chance for collisions that it's going to be fine for most use cases. I have not added any interface stuff for configuring the environment variables as I couldn't really find my way around all the places I'd have to edit to add it and the default values should in my opinion be fine for 99% use cases. * Add a 'fake' primary group for each user * First attempt att adding config to interface * Updated API to support new fields * Refactor code, update documentation and remove obsolete comment Simplify `GetRIDForGroup`, was a bit overcomplicated before. Add an additional class/struct `LDAPGroup` which is the new argument for `pi.GroupEntry` and util functions to create `LDAPGroup` from api.Group and api.User Add proper support in the interface for changing gidNumber and uidNumber starting points * make lint-fix for the migration files
This commit is contained in:
		| @ -2,6 +2,9 @@ package ldap | ||||
|  | ||||
| import ( | ||||
| 	"fmt" | ||||
| 	"strings" | ||||
| 	"math/big" | ||||
| 	"strconv" | ||||
| 	"reflect" | ||||
|  | ||||
| 	"github.com/nmcclain/ldap" | ||||
| @ -77,6 +80,34 @@ func (pi *ProviderInstance) UsersForGroup(group api.Group) []string { | ||||
| 	return users | ||||
| } | ||||
|  | ||||
| func (pi *ProviderInstance) APIGroupToLDAPGroup(g api.Group) LDAPGroup { | ||||
| 	return LDAPGroup{ | ||||
| 		dn:				pi.GetGroupDN(g), | ||||
| 		cn:				g.Name, | ||||
| 		uid:			string(g.Pk), | ||||
| 		gidNumber:		pi.GetGidNumber(g), | ||||
| 		member:			pi.UsersForGroup(g), | ||||
| 		isVirtualGroup:	false, | ||||
| 		isSuperuser:	*g.IsSuperuser, | ||||
| 		akAttributes:	g.Attributes, | ||||
| 	} | ||||
| } | ||||
|  | ||||
| func (pi *ProviderInstance) APIUserToLDAPGroup(u api.User) LDAPGroup { | ||||
| 	dn := fmt.Sprintf("cn=%s,%s", u.Username, pi.GroupDN) | ||||
|  | ||||
| 	return LDAPGroup{ | ||||
| 		dn:				dn, | ||||
| 		cn:				u.Username, | ||||
| 		uid:			u.Uid, | ||||
| 		gidNumber:		pi.GetUidNumber(u), | ||||
| 		member:			[]string{dn}, | ||||
| 		isVirtualGroup:	true, | ||||
| 		isSuperuser:	false, | ||||
| 		akAttributes:	nil, | ||||
| 	} | ||||
| } | ||||
|  | ||||
| func (pi *ProviderInstance) GetUserDN(user string) string { | ||||
| 	return fmt.Sprintf("cn=%s,%s", user, pi.UserDN) | ||||
| } | ||||
| @ -84,3 +115,26 @@ func (pi *ProviderInstance) GetUserDN(user string) string { | ||||
| func (pi *ProviderInstance) GetGroupDN(group api.Group) string { | ||||
| 	return fmt.Sprintf("cn=%s,%s", group.Name, pi.GroupDN) | ||||
| } | ||||
|  | ||||
| func (pi *ProviderInstance) GetUidNumber(user api.User) string { | ||||
| 	return strconv.FormatInt(int64(pi.uidStartNumber + user.Pk), 10) | ||||
| } | ||||
|  | ||||
| func (pi *ProviderInstance) GetGidNumber(group api.Group) string { | ||||
| 	return strconv.FormatInt(int64(pi.gidStartNumber + pi.GetRIDForGroup(group.Pk)), 10) | ||||
| } | ||||
|  | ||||
| func (pi *ProviderInstance) GetRIDForGroup(uid string) int32 { | ||||
|     var i big.Int | ||||
|     i.SetString(strings.Replace(uid, "-", "", -1), 16) | ||||
| 	intStr := i.String() | ||||
|  | ||||
| 	// Get the last 5 characters/digits of the int-version of the UUID | ||||
| 	gid, err := strconv.Atoi(intStr[len(intStr)-5:]) | ||||
|  | ||||
| 	if err != nil { | ||||
| 		panic(err) | ||||
| 	} | ||||
|  | ||||
| 	return int32(gid) | ||||
| } | ||||
|  | ||||
		Reference in New Issue
	
	Block a user
	 Lukas Söder
					Lukas Söder