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>

Reply via email to