On Mon, 9 Dec 2024 12:11:56 +0100 Corinna Vinschen wrote: > On Dec 8 08:13, Takashi Yano via Cygwin wrote: > > On Tue, 19 Nov 2024 21:54:44 +0100 > > Corinna Vinschen wrote: > > > No, we can't do that, it's too simple. > > > > > > Just kidding. > > > > > > This is so simple, I'm puzzled we never tried that before. Or, if we > > > did, it's a loooong time ago... > > > > > > If we really do this, we don't even need to call get_file_sd(). And it > > > should use NtOpenFile and reopen semantics i.e. pc.init_reopen_attr(). > > > Also, the sharing flags should allow all access. And the `effective' > > > argument needs to be taken into account. > > > > I have a question. What pc.init_reopen_attr() is for? I tested with > > pc.get_object_attr() instead, it works. > > init_reopen_attr() uses the "open by handle" functionality as in the > Win32 API ReOpenFile(). It only does so if the filesystem supports it. > Samba usually does, so it's not clear to me why pc.init_reopen_attr() > fails for you.
I didn't mean pc.init_reopen_attr() failed. Just I was no idea for what handle to be passed. > > What handle should I pass to pc.init_reopen_attr()? > > You could pass pc.handle(). Is pc.handle() in this scenario NULL, > perhaps? I have tried pc.handle() and suceeded. Thanks for advice! > > @@ -709,12 +615,44 @@ check_file_access (path_conv &pc, int flags, bool > > effective) > > desired |= FILE_WRITE_DATA; > > if (flags & X_OK) > > desired |= FILE_EXECUTE; > > - if (!get_file_sd (pc.handle (), pc, sd, false)) > > + > > + NTSTATUS status; > > + if (!effective && cygheap->user.issetuid ()) > > + { > > + /* Strip impersonation token temporarily */ > > + HANDLE tok = NO_IMPERSONATION; > > + status = NtSetInformationThread (GetCurrentThread (), > > + ThreadImpersonationToken, > > + &tok, sizeof (tok)); > > + if (!NT_SUCCESS (status)) > > + { > > + debug_printf("NtSetInformationThread() for stripping " > > + "impersonation token failed: %y", status); > > + __seterrno_from_nt_status (status); > > + return ret; > > + } > > + } > > You can simplify this: > > if (!effective) > cygheap->user.deimpersonate (); > > > + if (!effective && cygheap->user.issetuid ()) > > + { > > + /* Recover impersonation token */ > > + HANDLE tok = cygheap->user.imp_token () ?: hProcImpToken; > > + status = NtSetInformationThread (GetCurrentThread (), > > + ThreadImpersonationToken, > > + &tok, sizeof (tok)); > > + if (!NT_SUCCESS (status)) > > + debug_printf("NtSetInformationThread() for recovering " > > + "impersonation token failed: %y", status); > > } > > And this: > > if (!effective) > cygheap->user.reimpersonate (); This also works! Thank you very much! I'll submit v2 patch to cygwin-patches@cygwin.com. -- Takashi Yano <takashi.y...@nifty.ne.jp>