Can Microsoft Graph App Only Permissions be restricted? - outlook

I am developing an app to manage room bookings via Microsoft Graph. In the end, the app needs to read and cancel meetings that are booked into a certain room resource account.
Unfortunately, there is only the permission Calendars.ReadWrite which gives the app permissions to read and write every users calendar in the tenant, including private appointments.
I have not found any possibility to restrict the permissions or specify them more granular.
Does anyone know how to deal with this? (Or do I have to fall back again to service accounts and the old exchange web services, where I can give granular permissions to that service account?)
Thanks a lot in advance!

Application permissions imply the full the level of privileges of that scope, referenced here.
If you are scoping this specific mailboxes/calendars, you use delegated permissions with a functional account that has delegated permissions on those resources. We've had to do that before. It sucks, but that is the nature of App Permissions versus Delegate.
If you have are trying to script this, you could try the "client_secret_post" authentication method for the token acquisition mentioned here and in more detail with the OpenID Connect Spec and the OAuth 2.0 Spec.

You can now restrict the calendar/mailbox access an app will have using the New-ApplicationAccessPolicy PowerShell cmdlet. Using this you set the application up to use application permissions and then create an application access policy to limit the scope of these permissions.
There's an easy to follow guide on MS docs on how to set this up:
MS docs limit mailbox access

Related

How to programmatically access only one specific google drive without a service account

I am writing a server side python script with Pydrive which needs to store a file in a specific gdrive. Pydrive and this post suggest to use a service account.
However this would mean that with the credentials of this service account all gdrives are accessible and I would rather avoid that.
Ideal only one specific gdrive or all gdrives where one specific user has access to should be accessible.
Is it possible to give programmatically access to only one specific gdrive?
[Edit]
As mentioned in the comments I am apparently not looking for a OAuth flow.
I am looking for a server-to-server communication for accessing one specific google drive using the principle of least privilege access. Doing this with a service account + domain wide delegate and google drive r/w scope would mean that with this service account all google drives can be accessed which is not what I want.
Unfortunately there is a domain wide policy in place which forbids to share google drives to "other" domains. This means I can not use a service account without domain wide delegation and just share the drive with it.
I don't understand what you mean by "programmatically", when you already tag the question as oAuth - asking for oAuth2 flow, which is interactive. When there is nobody, who would press the buttons, this probably isn't the authentication flow you're looking for. Just share a directory with a service-account; no domain-wide delegation is required (with that enabled, there would be no need to share it).
One could even abstract the whole Drive API access credentials away by using a simple Cloud Function, which has to task to update one file; triggered through HTTP, utilizing the Drive API.
Possible approach - dummy account
You could designate a new account that will be your "service account". In reality it won't be an actual service account, it will just be a dummy account that you can call something like "gdrivebot#yourdomain.com". Then you can share only what is absolutely necessary with it. I think this would be the only way to get that level of fine-grained control that you are looking for. This would require your admin to designate a new account just for this purpose though.

Google Drive Access - Service Account or OAuth - To read/write user files

I have a .NET console application that performs operations on files. I would like to allow clients to give us access to their Google Drive accounts so we can read and write files. Our console application runs as a service so there is no way for the user to interact with it and authorize our access to their Google Drive account.
I was looking at using a Google Service Account for application level authentication until I learned that a Service Account does not have access to the Google Drive folder of the user that sets up the Service Account. This sort of defeats the purpose because it is the client's Google Drive account I am looking to gain access to.
I saw a workaround posted by SO member #pinoyyid posted in this SO answer where the refresh token can be generated using Google's Oauth2 Playground, but I am concerned that the refresh tokens could expire and user intervention would be needed again to generate another one.
Another response mentioned the solution was to create the Service Account and then share the user's Google Drive account with the Service Account.
What is the recommended approach by Google? How best to gain access to a Google Drive account while only requiring the owner to authenticate on a one-time basis, yet allowing them the ability to revoke access at any time?
Both Service Account and a stored OAuth Refresh Token are viable approaches. Each has its pros and cons.
A Service Account will work where your users only need to grant access to a specific folder which they can share to the SA. Be aware that any files the SA creates are owned by, and consume quota of, the SA. You can't "share the user's Drive account to the SA", you can only share individual folders.
Storing a RT is the more permissive option. You wouldn't use the OAuth playground as described in my answer that you referenced as that's far to clunky to ask users to go through. Instead you would need to write your own registration/authorisation service (you can use AppEngine, Lambda, etc - so it's not difficult to write and host).

Services Creating Services - Assigning SC_MANAGER_CREATE_SERVICE to a User

I'm trying to create a Windows service that has the right to create additional services. But I'd prefer not to make this service run with an Administrative login.
The users rights are otherwise quite limited - I just need it to be able to spin-up a service on request.
I've seen mention online that SC_MANAGER_CREATE_SERVICE is a permission you can now assign and/or change, but I haven't seen much on how that is done. There is mention of being able to change permissions for individual services via subinacl, via OpenSCManager and the - gulp - sc command. But these examples show how to change the permissions on a single service, not how to give a user SC_MANAGER_CREATE_SERVICE permissions.
However, I've noticed that the documentation on CreateService specifically says that it requires administrator privilages - so perhaps it's simply not possible.
Am I going to have to start the service with an admin account? Or does anyone know another trick?
See Service Security and Access Rights:
To get or set the security descriptor for the SCM, use the QueryServiceObjectSecurity and SetServiceObjectSecurity functions with a handle to the SCManager object.
Be aware that having the right to create services gives you effective administrator access, since you can create a service to run as local system. So you do need to be careful not to grant that right to accounts that untrusted users have access to, to make sure that all accounts with that right have strong passwords, and so on.
This also means that if your system service is compromised by a remote code execution vulnerability you haven't gained anything, the attacker will still be able to get control of your system. If the service is at a high risk of direct attack, it may be wise to instead have a second service that is responsible only for the tasks that require special privilege. However, for a service that is unlikely to be directly attacked, or is considered reasonably secure, running without administrator privileges (other than the ability to create services) may prevent a less severe vulnerability from being exploitable, or limit the damage caused by a non-security-related bug.
See also Granting service control manager access permission to user outside of administrator group on Server Fault, the answer shows how to change the SCM permissions from the command line.
Try opening an handle to the service control manager with the WRITE_DAC access right, and change the security of it by calling SetServiceObjectSecurity to change the dacl of the service control manager. Don't forget to do the same thing for the service registry key (HKLM\SYSTEM\CurrentControlSet\Services) using RegOpenKeyEx and RegSetKeySecurity function.
WARNING
Be aware that this is a potential security risk since it would allow a standard user account to elevate its privileges to SYSTEM.

Looking for a way (preferably an API) to determine Effective Permissions on Active Directory object

We have a custom Active Directory integrated web app that helps users perform some self-service on their accounts (e.g. update photo, change phone number, reset password etc.) Our app runs on domain-joined servers, as Local System, and is thus able to authenticate to the AD using the server account(s).
We use a service connection point, that the app's clients use to locate an instance of our app. (Our app clients are hard-coded to look for certain keywords which are published on the servie connection point's keywords attribute.)
We recently had a situation wherein someone (we believe accidentally) changed the keywords on one of the service connection points resulting in an outage, since the clients could no longer find our SCP when querying the AD for our keyword(s).
The customer is a bit upset about this and wishes for us to provide them the ability to determine who can change the keywords on our SCPs. This feedback was passed on from our sales guys to us, and now we need to provide some way of helping them figure out who can change the keywords on our SCPs.
So, we're looking for an API to help us to determine Effective Permissions on our Active Directory service connection point objects, so we can alleviate this situation for the customer. We couldn't quite find an Effective Permissions / Access API that could help us list all the users who have effective write access to the keyword and other attributes on our SCPs.
Is there an API/other way that one can use to determine Effective Permissions on an Active Directory object?
It needs to be able to list all the users who have a specified access on a specified set of attributes of an Active Directory object.
This stack overflow post may be able to help you. LINQ to LDAP should also allow you to access the information pretty easily as well.

WIN32 Logon question

We have developed a ASP.NET 3.5 web application with Web Server 2008 and has implemented a custom authentication solution using active directory as the credentials store. Our front end application uses a normal login form to capture the user name and password and leverages the Win32 LogonUser method to authenticate the user’s credentials. When we are calling the LogonUser method, we are using the LOGON32_LOGON_NETWORK as the logon type.
The issue we have found is that user profile folders are being created under the C:\Users folder of the web server. The folder seems to be created when a new user who has never logged on before is logging in for the first time. As the number of new users logging into the application grows, disk space is shrinking due to the large number of new user folders getting created.
I need to get the token back after the authentication (authenticated \ password locked \ wrong password ) its futher use and based on logic showing different web pages
Has anyone seen this behavior with the Win32 LogonUser method?
Please answer the following issue:
Is it possible to disable this behavior to create the folder as taking 2.78 MB of space for every new user and it eating my disck space?
I have tried LOGON32_LOGON_BATCH but it was giving an error 1385 in authentication user.
For any solution related to LOGON32_LOGON_BATCH, can you please confirm if that will stop creating the folders at location C:\users.
Also for any possible solution I need either
I am able to disable the folder to be created at C:\user or
Any other option to authenticated user which will not creat folders.
Pass LOGON32_LOGON_BATCH and grant the users permission to log on as a batch job on that machine using Group Policy.
The MSDN documentation for LogonUser recommends LOGON32_LOGON_BATCH as the logon type for web services:
This logon type is intended for batch
servers, where processes may be
executing on behalf of a user without
their direct intervention. This type
is also for higher performance servers
that process many plaintext
authentication attempts at a time,
such as mail or Web servers. The
LogonUser function does not cache
credentials for this logon type.
Have you tried that?
You don't write any information about the version of products (.NET, Windows Server which you use) and the best answer on your question can depend on this. Moreover the best way for your solution depend on what you want to do with the users token after logon. Do you really want to use this token or you want only verify the user? So I try to answer most general on your question.
In general, error 1385 (ERROR_LOGON_TYPE_NOT_GRANTED) means following (see http://support.microsoft.com/kb/155012/en):
A user has requested a type of logon,
such as interactive or network, that
was not granted. An administrator has
control over who may logon
interactively and through the network.
There are SE_BATCH_LOGON_NAME and SE_DENY_BATCH_LOGON_NAME (NTSecAPI.h) privileges which can be disabled/enabled in your case (see http://msdn.microsoft.com/en-us/library/bb545671%28VS.85%29.aspx for description). Use Process Explorer started with administrator rights (see http://technet.microsoft.com/en-us/sysinternals/bb896653.aspx) to see which privileges has a process and which from there are enabled (see "Security" tab of a process). If your account used for the application pool don't have SE_BATCH_LOGON_NAME granted or this privilege is not enabled before call of LogonUser, you should add the corresponding code in your program.
By the way sometimes you don't really want to do much with an user account and want only verify a password. To do this you can use an old way with SSPI (see http://support.microsoft.com/kb/180548/en) which are used inside of LogonUser implementation. This way is the most smart and quick way to verify an user account which I know.
You can look at "The SSPI Workaround" (see http://alt.pluralsight.com/wiki/default.aspx/Keith.GuideBook/HowToGetATokenForAUser.html) for more information of usage SSPI in .NET 2.0.

Resources