lithnet / googleapps-managementagent

Google Workspace Management Agent for MIM 2016
MIT License
12 stars 4 forks source link

Export users as externalMember #33

Closed MichalWirth closed 6 years ago

MichalWirth commented 6 years ago

Hi @ryannewington,

during implementation of complex group members logic we faced a problem with sending users as externalMember to Google.

We get an error saying "The value test.user@contoso.com cannot be exported as externalMember as it is a known internal domain. It should be exported as Member". The error is completely clear, however we have multiple cases that we do not want to create user object in Google, but we want to include this user as externalMember to allow him to receive messages. From Google point of view it is doable since we are able to add such member through API using a script, so I suppose that there is a validation in MA which prevents such cases.

Is there any option to modify this behaviour and skip this check?

King regards, Michal

ryannewington commented 6 years ago

Hi @MichalWirth,

Interesting. I assume you have a mailbox for that user in another service somewhere?

The MA was built on the assumption that Google is authoritative for all mailboxes in the domain's that it is configured for. So we extract a list of those domains, and use it to determine who is 'internal' and who is 'external'. As you are aware, google doesn't actually distinguish between the two. It just sees group 'members' as email addresses.

FIM however has a 'reference' attribute type for tracking relationships between objects. This is what allows us to 'add an object to a group' by reference, and have FIM keep track of DN changes to it.

So, when the MA downloads the list of members, it has to know whether to present them to FIM as references (member attribute) or strings (external member attribute). The domain list is how we split the list in two. We could turn off the export check, but that would then mean upon import, the user would be seen as an 'internal' member, and a reference attribute value imported. FIM would see this as an unexpected member reference, and delete it. It would also see an exported-change-not-reimported error on externalMember and re-export it. Messy.

So in order to export these 'non-tenant' members of your domain, we'd need to export them to the 'members' attribute, rather than 'externalMembers'. This would then mean we would need to have a reference (object) in FIM for them. I'm wondering if I can update the code to allow you to export 'contacts' as members of groups. This would mean you'd need to create a contact object in FIM, export that to Google as a domain shared contact. Then you can add that contact object to the group as a regular member, instead of the external member text field. Would that be a suitable workaround?

Ryan

MichalWirth commented 6 years ago

Hi @ryannewington,

Thank you for the explanation. It cleared out my understanding of MA and Google.

Yes, this is a kind of a hybrid mail solution when we have Exchange and Google for mailboxes. The configuration is not typical and contradicts MIM logic unfortunately.

Basically we have all users in Exchange and AD (including groups assignment), but not all of them are created in Google. However we still want to allow such users to send/receive messages using groups, so we add them to the groups in Google as plain email address even if they have email domain same as primary domain in Google.

I completely understand reference attribute behaviour, but was not aware how it looks in Google. Based on your information I understand that in Google all members are just email addresses regardless there is an object in Google or not. Difference is only on MA side where we identify users if they are internal or external using domain name. I assume that members and externalMembers attributes are only on MA side, in Google there is only members attribute. Please correct me if I am wrong.

Provisioning contacts is an idea that I was also thinking about, but we would like not to create additional objects in Google. We consider this as last resort. I was thinking if we could modify MA to treat members as string multivalve attribute instead of reference, and we could send all email addresses that needs to be member of a group regardless if there is an account in Google or not.

We are not synchronising member attribute from MIM, but we have a Helper DB which calculates who should be member of a group in Google. For calculation we use members attribute from MIM and also authOrig and dLMemSubmitPerms attributes from AD, so DB can push out list of email addresses or references to Google. From our point of view we do not need to use reference attribute.

Do you think it is possible to modify MA in such way or my thinking is wrong and Google needs reference?

Regards, Michał

ryannewington commented 6 years ago

Hi @MichalWirth,

You are correct in that externalMembers and members is a construct that only exists in the MA for the purpose of separating reference attributes from non-reference attributes.

I can certainly make some code changes to treat the members attribute as a multivalued string. But just to confirm, you do realize you would not be able to push any reference-type member attributes to this value? You'd only be able to push strings. If a user's email address changed, you could end up with a race condition where Google 'changes' the contents of your group member list, but FIM hasn't processed the change to your MV string attribute yet. FIM may try remove what it considers the non-existent member, and try put the old one back. You'd need a really careful and thoroughly tested run schedule to avoid running into these issues. It may be a significant referential integrity challenge to solve.

Let me know if you'd like me to proceed with the code changes so you can test in more detail.

Alternatively, while I understand it's more overhead, I can also look to make the changes to support the contacts model, which will adding overhead of additional objects to manage, would resolve the referential integrity problems.

Ryan

MichalWirth commented 6 years ago

Hi @ryannewington,

I think it will be easier to go with members attribute as string multivalue without checking primary domain. This will allow us to use existing calculation mechanizm almost intact and we will receive expected result in Google.

Only values are good for us, because our SQL mechanizm calculates all email addresses which needs to be added to Google group members. We do not need to use reference value.

Regarding your concern about data integrity it should not be an issue as we use PowerShell script to execute synchronisation runs so we can ensure to run MAs in specific order to export proper values to Google.

Please kindly let me know how we could proceed with such change in Google MA.

Regards, Michal

ryannewington commented 6 years ago

@MichalWirth

Do you plan on using the manager/owner fields of groups as well as members?

Ryan

ryannewington commented 6 years ago

@MichalWirth Never mind the previous question.

I've created a build for you with the feature you requested. I don't have the utmost faith in the concept working overall, so I've added support for the contacts option as well.

To test the members-as-string option, you will see a new option at the bottom of the schema configuration page 'Group member attributes type'. Change this from reference to string. This will remove the 'members', 'manager', and 'owner' attributes, and replace them with 'member_raw', 'manager_raw', 'owner_raw'. The 'external' attributes will also no longer appear.

image

If that doesn't work out, I suggest you fall back to the contacts option. You'll need to make a change to the MA config to allow this to work as well. On the global settings page, delete the text in the 'contact dn prefix' box. This will mean contact DNs will be email addresses only (they are usually prefixed with contact:, and you'll then be able to export them as regular group members. The trade off if you won't be able to have a contact with the same email address as a user.

image

Here's the build. Let me know if you encounter any problems. Lithnet.GoogleApps.MA.Setup.msi.zip

MichalWirth commented 6 years ago

Hi Rayan,

Thank you for the modification.

We deployed new version and it works as expected. Everything is now perfectly synchronized.

Thank you for your help.