...before calling any of its method. It's no safe bet that
it's already initialized when calling s4uauth and adding it
to load_user_profile certainly doesn't hurt.
Signed-off-by: Corinna Vinschen <corinna@vinschen.de>
In case of a local machine account login, pi.lpProfilePath points
to the buffer returned by NetUserGetInfo, but NetApiBufferFree
is called prior to calling LoadUserProfileW. Fix by copying over
usri3_profile to the local userpath buffer, just as in the AD case.
Signed-off-by: Corinna Vinschen <corinna@vinschen.de>
This never really worked. While at it, restructure code to
do common stuff only in one spot. Improve debug output.
Signed-off-by: Corinna Vinschen <corinna@vinschen.de>
Inspecting the content of case-sensitive directories
on remote machines results in lots of errors like
disappearing diretories and files, file not found, etc.
This is not feasible as default behaviour
Signed-off-by: Corinna Vinschen <corinna@vinschen.de>
A sleep is required on Windows 10 64 bit only before calling
RegisterClassW in the timerfd thread, and only when running
under strace. One of the child processes inheriting the timerfd
descriptor will get a STATUS_FLOAT_INEXACT_RESULT exception inside
of msvcrt.dll. It's apparently some timing problem. It occurs
in 4 out of 5 runs under strace only. WOW64 and Windows 7 64 bit
don't have this problem.
Signed-off-by: Corinna Vinschen <corinna@vinschen.de>
The share section was created using the PAGE_SIZE constant,
but PAGE_SIZE is 64K. Fix that by using wincap.page_size()
instead, which returns the desired actual page size of 4K.
Signed-off-by: Corinna Vinschen <corinna@vinschen.de>
timerfd_tracker and timerfd_shared classes:
- Just because handles are shared, we don't have to store them in
shared memory. Move share handles into timerfd_tracker class.
- Drop shared instance counter since it's not required anymore.
timerfd_shared only stores the actual timer data.
- Drop timerfd_shared::create, just set clock id.
- Drop timerfd_shared::dtor, it's not required anymore.
- Drop timerfd_tracker::close, just call dtor where required.
- Rename timerfd_tracker::increment_instances to timerfd_tracker::dup.
It's the only reason it exists...
- timerfd_tracker::dtor now checks the non-shared pointers for NULL
before attempting to close them.
- timerfd_tracker::dtor handles decrementing the local instance count
by itself.
- Add a method timerfd_tracker::init_fixup_after_fork_exec to set
non-shared pointers to NULL. Together with the dtor patches it
fixes a problem with close_on_exec timerfd descriptors.
- Fix a bug in handling the thread synchronization event. It's
actually nice to create it before using it...
- Drop using sec_none{_nih} in InitializeObjectAttributes. It's
an unnecessary roundabout route just to get a NULL pointer.
- Slightly rework timechange window handling.
- Add more comments to explain what happens.
fhandler_timerfd:
- Drop cnew macro, it just hides what happens.
- fhandler_timerfd::fixup_after_exec now calls
timerfd_tracker::init_fixup_after_fork_exec first, so a subsequent
call to timerfd_tracker::dtor only works on valid handles.
- fhandler_timerfd::close directly calls timerfd_tracker::dtor now.
- Drop dtor call in fhandler_timerfd destructor.
Signed-off-by: Corinna Vinschen <corinna@vinschen.de>
timerfd_tracker::fixup_after_fork_exec always tries to restore
the shared timer region at the same address as in the parent.
This is entirely unnecessary and wasn't intended, rather some
kind of copy/paste thinko. Fix that. Print NtMapViewOfSection
status code in api_fatal on failure for debugging.
Signed-off-by: Corinna Vinschen <corinna@vinschen.de>
The "optimized" condition to recognize an unarmed timer was plain
wrong. Replace it by checking the stored it_value against 0.
Signed-off-by: Corinna Vinschen <corinna@vinschen.de>
The child process needs access to the handle to be able to
unload it when switching user context.
Signed-off-by: Corinna Vinschen <corinna@vinschen.de>
Does this work? There's not much feedback given.
TODO: We might want to try unloading the user profile at process
exit as well, FWIW.
Signed-off-by: Corinna Vinschen <corinna@vinschen.de>
curr_primary_token is either NO_IMPERSONATION or the external_token
or the internal_token, so it's never required to be closed by itself.
Signed-off-by: Corinna Vinschen <corinna@vinschen.de>
Commit 649911fb40 avoids the
calls to NetUserGetGroups and NetUserGetLocalGroups since
these can take a lot of time. The same problem potentially
occurs when loading the user profile. The code fetches
the roaming profile path calling NetUserGetInfo, which also
can be rather slow.
To avoid this problem, fetch the profile patch using LDAP.
Also, don't bail out early if the user's registry hive already
exists. This may result in outdated information.
Signed-off-by: Corinna Vinschen <corinna@vinschen.de>
NetUserGetGroups and NetUserGetLocalGroups sometimes take a lot of time
(up to more than 2 mins) for no apparent reason.
Call s4uauth to generate an identification token for the user and fetch
the group list from there. This is *much* faster.
Keep the old code only for the sake of WOW64 on Vista and Windows 7,
which don't implement MsV1_0S4ULogon.
Signed-off-by: Corinna Vinschen <corinna@vinschen.de>
s4uath was only callable to create an impersonation token so
far. Rework the function to allow creating an identification
token for informational purposes even from untrusted processes.
Take domainname and username instead of a passwd pointer to be
more multi-purpose.
Signed-off-by: Corinna Vinschen <corinna@vinschen.de>
Commit 4e34a39b5c made sure all user and
group names are case-correct, but it introduced a hefty performance hit
on starting the first Cygwin process.
Adding an ldap call for each AD group in a user token takes its toll in
bigger AD environments with lots of groups in a user token. Real-life
example: 300 groups w/ roundtrip time to the LDAP server of 0.25 secs
per call...
Signed-off-by: Corinna Vinschen <corinna@vinschen.de>
Up to Vista CreateProcessAsUser only worked with primary tokens,
so convert S4U impersonation token to primary token. MSDN still
documents it that way, but actually an impersonation token is
sufficient since Windows 7.
Signed-off-by: Corinna Vinschen <corinna@vinschen.de>
Under WOW64 on 64 bit Windows 7, MsV1_0S4ULogon appears to be
unimplemented, probably under Vista as well. Re-enable
create_token method, to allow basic seteuid on W7 WOW64 and
Vista as well.
Signed-off-by: Corinna Vinschen <corinna@vinschen.de>
for domain accounts we try KerbS4ULogon first, MsV1_0S4ULogon
second. But we only fetch the package id for the supporting
authentication package (Kerberos/MsV1_0) once at the start.
Duplicate LsaLookupAuthenticationPackage call and move into the
Kerb/MsV1_0 branches so that it fetches the correct package id
for the method we call next.
Curious enough this worked before. Apparently both methods
work with the MICROSOFT_KERBEROS_NAME_A package id. However,
requesting and using the right authentication package id is
the prudent thing to do.
Signed-off-by: Corinna Vinschen <corinna@vinschen.de>
This reverts commit 7c34811440.
This potentially allows to circumvent OpenSSHs user/group name matching,
unless the Admin knows to add every local user twice or to use patterns,
e.g.:
Match user MACHINE+user,.+user
Match user *+user
Signed-off-by: Corinna Vinschen <corinna@vinschen.de>
Commit c1023ee353 changed the way
path_conv::binmode() works. Rather than returning three states,
O_BINARY, O_TEXT, 0, it only returned 2 states, O_BINARY, O_TEXT. Since
mounts are only binary if they are explicitely mounted binary by setting
the MOUNT_BINARY flag, textmode is default.
This introduced a new bug. When inheriting stdio HANDLEs from native
Windows processes, the fhandler and its path_conv are created from a
device struct only. None of the path or mount flags get set this way.
So the mount flags are 0 and path_conv::binmode() returned 0.
After the path_conv::binmode() change it returned O_TEXT since, as
explained above, the default mount mode is textmode.
Rather than just enforcing binary mode for path_conv's created from
device structs, this patch changes the default mount mode to binary:
Replace MOUNT_BINARY flag with MOUNT_TEXT flag with opposite meaning.
Drop all explicit setting of MOUNT_BINARY. Drop local set_flags
function, it doesn't add any value.
Signed-off-by: Corinna Vinschen <corinna@vinschen.de>
When recognizing a negative pid, optind is off by one. The
code correcting this has been erroneously removed by commit
8de660271f. Revert that.
Signed-off-by: Corinna Vinschen <corinna@vinschen.de>
The solution from commit 9a3cc77b2a
didn't work for foreign domain accounts. Rather than calling
LookupAccountSid we now use the info when we fetch it anyway
via LDAP or Net*GetInfo. Only in case of domain groups we have
to add an LDAP call explicitly.
Signed-off-by: Corinna Vinschen <corinna@vinschen.de>
Make sure a domain+username fits into the local name buffer.
The former buffer size didn't take adding a domain name to
a really_really_long_user_name into account.
Signed-off-by: Corinna Vinschen <corinna@vinschen.de>
When looking up valid accounts by name, LookupAccountName returns
a SID and a case-correct domain name. However, the name was input
and LookupAccountName is case-insensitive, so the name is not
necessarily written the same way as in SAM or AD.
Fix that by doing a reverse lookup on the just fetched SID. This
fetches the account name in the correct case. Override the
incoming name with the case correct name from LookupAccountSid.
Signed-off-by: Corinna Vinschen <corinna@vinschen.de>