LsaEnumerateAccountRights always returns "File not found" - security

I'm calling the Advapi32.dll LsaEnumerateAccountRights function having a policy handle from LsaOpenPolicy and an account SID from LookupAccountName.
However, try as I might, I'm always getting back 0xC0000034 which after translation by LsaNtStatusToWinError gives me "The file referenced cannot be found."
Which isn't a whole lot of good. My code handles this and goes on to grant the account SID the SeServiceLogonRight using LsaAddAccountRights, so I know that the policy handle and the account SID are fine as that would bomb out if something was wrong with one of those.
The end result is that the account does have the right it needs so overall the code works.
However, I'm using this within an MSI custom action, the Install checks to see if the account has the right and if it doesn't (or it fails as above) it grants the right and remembers it has done it in the install state. If a rollback happens and it added the right it then removes it. We never remove in an uninstall as other applications may have been installed using the same domain account that the services we run use.
So the problem is when an MSI performs a rollback - it will always remove the right as it always thinks it has added it. So checking the rights using LsaEnumerateAccountRights is used for this - but I just can't get it to work.
Any idea - please note that I'm using c# with DllImport attribute to expose the Win32 functions, and I'm not the worlds best Win32 programmer having been Unix before C#!

I have been struggling with this, too, but have just cracked it...
Retrospectively, I now see there was a clue in the msdn documentation:
"The accounts returned by this function hold the specified privilege directly through the user account, not as part of membership to a group."
See: link text
Get the policy handle from LsaOpenPolicy() and an account SID from LookupAccountName() exactly as you said.
If the username you entered was the name of a group ("Users", "Administrators", etc) then LsaEnumerateAccountRights() works fine and enumerates all the rights for the group.
If you call it on a username whose rights derive solely from the groups of which it is a member, then it returns 0xc0000034 (= Windows error 2 - The system cannot find the "file" specified), meaning (we now realise) "cannot find any individually assigned additional rights". It seems that the Windows Error 2 translation is a catch-all for "what you were looking for has not been found".
Now...
If you have ntrights.exe, run it... for example:
ntrights +r SeNetworkLogonRight -u MyUserName
Then, LsaEnumerateAccountRights() works fine, returns without error and enumerates a single right, "SeNetworkLogonRight".

I have recently run up against this same problem. In my testing with this issue it appears that the LookupAccountName call returns a security principal rather than the full SID. The actual failure seems to be that the section within the SID where the user rights would be is either not there or shortened to only the logon right.
Performing a LookupAccountName call on the current logged in user and then trying to LsaEnumerateAccountRights against that SID results in only the user logon right. Even though clearly, there are many other rights attached. Trying to retrieve any other users, other than the logged on user, successfully returns a SID. However, that SID will not have any user rights in it.
I have tested this on no domain workgroup systems and member systems of domains both as admin and regular users. The LookupAccountName call when successful, always results a SID that does not contain the full set of user rights.
I can only assume that if a complete SID could be obtained from the Security Database, then the LookupAccountName would properly iterate the rights.

I too have the exact same problem. Somebody suggested I get the SID via WMI with this query:
SELECT * FROM Win32_Account WHERE domain = 'ntdomain' AND name = 'username'
I tried it, using ConvertStringSidToSid() to get the magic blob LsaEnumerateAccountRights() expects and... same error. "The system cannot find the file specified."

I meet the same problem, it is because you dont assign spefic privledge to the user, so the user priveldge is empty, if you add one to it, it wont fail.
Call the same function with a group you can see everything working correctly.

Related

Microsoft graph API: Accessing presences information via an Application scope

I'm trying to access user's presence off of https://learn.microsoft.com/en-us/graph/api/presence-get?view=graph-rest-1.0&tabs=http
I've granted my AD app Presence.ReadWrite.All which is described as "Allows the app to read all presence information and write activity and availability of all users in the directory without a signed-in user. Presence information includes activity, availability, status note, calendar out-of-office message, time zone and location.
".
There seems to be a bit of a conflict between the docs and what the permission's name is - the docs seem to imply it doesn't work with an application scope, while the permission name/description seems to say it does.
The error i'm getting is Forbidden. This seems to be different from accessing a resource with insufficient permissions (which straight up says InsufficientPermissions).
The docs are clear that you can't do this with Application scope. That means even if the particular permission seems like it should work, it might be because it's used in that way for another endpoint. Notice that, for instance setPresence and clearPresence both support Presence.ReadWrite.All.
What's really crazy though is that neither getPresence (your endpoint) nor (get Presence for Multiple Users)[https://learn.microsoft.com/en-us/graph/api/cloudcommunications-getpresencesbyuserid?view=graph-rest-1.0&tabs=http] support Presence.*Read*Write.All - there is no supported read scenario!
From what I can see, your best bet is to keep an eye on this request and to upvote it. Microsoft (Darrel Miller) is quite active there from last year - perhaps there's an update coming.

How can I supress a specific warning in a PowerShell script?

I am working on a PowerShell script that very often produces the same, irrelevant warnings. This warning pollutes the script output, and I want to get rid of it. However, I don't think it is a good practice to omit all warning, so I was wondering if it would be possible to omit very specific warnings?
In my case, I want to remove the following warnings:
WARNING: TenantId 'xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx' contains more
than one active subscription. First one will be selected for further
use. To select another subscription, use Set-AzContext.
WARNING: Unable to acquire token for tenant
'xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx' with error 'You must use
multi-factor authentication to access tenant
xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx, please rerun 'Connect-AzAccount'
with additional parameter '-TenantId
xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx'.'
Any idea how can this be achieved?
First I'd recommend that you use the most recent version of Az.Accounts to ensure that you are not facing any knowns issues (currently version 2.5.2).
When running Connect-AzAccount we populate the local context based on the first 25 subscriptions returned. It seems that one of those requires MFA therefore cannot get a token.
To avoid the warning, try to be specific of the subscription/tenant that you want to use.

Get current logged in user's email address is timming out

I am using the Membership.GetUser(User.Identity.Name).Email method to try and get the current user email address but its timing out, I just have one line, on which I declare and assign the returned value of the method to a variable
Here is my one line of code string userEmail = Membership.GetUser(User.Identity.Name).Email;,
I have tried this code both with or without the username parameter. I also tried checking first if user is authenticated but once it gets to this line it times out, I have also tried doing it totally from a different method.
Note: Windows auth is used on the web app
Membership is from ASP.NET Membership, not Identity. You need to use:
var user = UserManager.FindById(User.Identity.GetUserId());
Then, you access the Email property off that user object.
UPDATE
I got thrown by your use of the [asp.net-identity] tag. However, the same over all point applies. Membership is from a completely different authentication system than Windows Auth. When using Windows Auth, your user information comes from AD, so you simply need to add a UserPrincipal extension if you need additional information. See my answer in this related question.

Web user is not authorized to access a database despite having Editor access in the ACL

In my XPages application, web users can perform a self-registration. In the registration process, a user document for the web user is created in the address book and the user is added to a group that has Editor access for the database. After executing show nlcache reset on the Domino server, the user can login to and access the application.
In ~98% of all registrations this works perfectly fine. However, sometimes new users cannot enter the application after the login because, according to the Domino server, they "are not authorized to access" the database. The login must have worked because the user id is correct. The exact same user id can also be found in the Members field of the group that has Editor access to the database. To additionally verify the user's access level, I executed NotesDatabase.queryAccess() with the user's id. It returned 0, which is the ACL default and means "No Access". Yet, there are dozens of users in the same ACL group which have absolutely no problem with accessing the database.
At the moment, we "circumvent" this problem by manually removing the user's document from the address book as well as remove him/her from the Members of the ACL group. Afterwards we ask the user the re-do the self-registration with the exact same information as before. Up to now, this second registration has always worked and the user can access the application. Yet, this is not a real solution, which is why I have to ask if anyone knows what could be the problem?
Don't create entries in the address book directly. Use the adminp process for registration. To minimize perceived delay send a validation/confirmation message the user has to click.
Comment of 12/02/2015 seems to be the correct Answer:
Check if the self-registrated user has TWO consecutives spaces in his name, (could be because trailling space too)
In group domino do a FullTrim. So we have
John<space><space>Smith
that is not in group XXX because in the members it's:
John<space>Smith.
This may have something to do with the frequency at which the views index are refreshed in the names.nsf
Since the access control is done groups in the ACL, the server will "know" which user belongs to which group only after the views index have been updated.
In a normal setting, this can take a couple of minutes.
You can test this hypothesis by forcing an index refresh, either with CTRL-MAJ-F9 from your Notes client (warning, can take very long depending on network and number of entries in the names.nsf) or with the command
load updall -v names.nsf
... or by having the users wait a little while and try again 5min later.
Ok, first a question. If you let the user wait a couple of minutes will the access then work? I.e. is it a refresh/caching problem - or an inconsistency in the way you add the user to the group?
I assume that the format of the user name is correct as it works in most cases (i.e. fully hierarchical name)... Is there anything "special" about the names that do not work?
I do a similar thing (and has done several times) - although with some differences :-)
I typically use Directory Assistance to include my database with a "($Users)" view. When I update anything in this view I do a view.refresh() on the view (using Java). I typically do not use groups in these type of applications (either not applicable - or I use OU's or roles for specific users). I am not sure how the group membership is calculated - but I guess you could try to locate the relevant view (though none of them seemed obvious when I looked) - and do a refresh on it.
/John

hgweb alternatives to allow_push

I've got Mercurial running on IIS7 fine. One thing that is frustrating is that allow_push will only take a list of usernames rather than a group.
To that end, I was wondering if it'd be possible to use a hook to carry out this task. i.e. by passing in the authenticated username, you could check on demand whether the user has the appropriate access. That's all fine if you can pass the username into the hook, for example:
[hooks]
prechangegroup = echo %username%
Unsurprisingly, this always returns the account that IIS is running on. Is there a way to either get allow_push to respect groups - or to pass the logged on user into the prechangegroup hook?
Alternative approaches welcome.
This isn't ideal - and I'd rather do as above. The alternative approach I've taken is to have an external process set the permissions on the folders in IIS for read and execute, allow_pull and allow_push in the hgrc for the repository as appropriate.
In terms of shortcomings:
Its another process that needs to know about the location of the repository.
The process needs a mechanism to find out about updates to the groups (i.e. polling).

Resources