Skip to content

Commit

Permalink
Add named pipe impersonation
Browse files Browse the repository at this point in the history
  • Loading branch information
kotauskas committed Jun 13, 2024
1 parent 0735668 commit 5bcd669
Show file tree
Hide file tree
Showing 4 changed files with 44 additions and 8 deletions.
3 changes: 2 additions & 1 deletion src/os/windows.rs
Original file line number Diff line number Diff line change
Expand Up @@ -7,10 +7,11 @@ pub mod security_descriptor;
pub mod unnamed_pipe;
//pub mod mailslot;

mod impersonation_guard;
mod path_conversion;
mod share_handle;

pub use {path_conversion::*, share_handle::*};
pub use {impersonation_guard::*, path_conversion::*, share_handle::*};

mod file_handle;
mod limbo_pool;
Expand Down
21 changes: 21 additions & 0 deletions src/os/windows/impersonation_guard.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
use crate::{DebugExpectExt, OrErrno, ToBool};
use std::fmt::{self, Debug};
use windows_sys::Win32::Security::RevertToSelf;

/// [Reverts impersonation][rd] when dropped.
///
/// [rd]: https://learn.microsoft.com/en-us/windows/win32/api/securitybaseapi/nf-securitybaseapi-reverttoself
pub struct ImpersonationGuard(pub(crate) ());
impl Drop for ImpersonationGuard {
fn drop(&mut self) {
unsafe { RevertToSelf() }
.to_bool()
.true_val_or_errno(())
.debug_expect("failed to revert impersonation")
}
}
impl Debug for ImpersonationGuard {
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
f.write_str("ImpersonationGuard")
}
}
1 change: 0 additions & 1 deletion src/os/windows/named_pipe.rs
Original file line number Diff line number Diff line change
Expand Up @@ -35,7 +35,6 @@
//! documentation.
// TODO(2.3.0) improve docs and add examples
// TODO(2.3.0) client impersonation
// TODO(2.3.0) raw instance functionality
// TODO(2.3.0) transactions

Expand Down
27 changes: 21 additions & 6 deletions src/os/windows/named_pipe/stream/impl.rs
Original file line number Diff line number Diff line change
Expand Up @@ -9,13 +9,16 @@ mod send;
mod send_off;

use super::*;
use crate::os::windows::{
decode_eof,
named_pipe::{
c_wrappers::{self as c_wrappers, hget},
PipeMode,
use crate::{
os::windows::{
decode_eof,
named_pipe::{
c_wrappers::{self as c_wrappers, hget},
PipeMode,
},
AsRawHandleExt, FileHandle, ImpersonationGuard, NeedsFlushVal,
},
FileHandle, NeedsFlushVal,
OrErrno, ToBool,
};
use std::{
io::{self, prelude::*},
Expand Down Expand Up @@ -111,4 +114,16 @@ impl<Rm: PipeModeTag, Sm: PipeModeTag> PipeStream<Rm, Sm> {
pub fn set_nonblocking(&self, nonblocking: bool) -> io::Result<()> {
c_wrappers::set_nonblocking_given_readmode(self.as_handle(), nonblocking, Rm::MODE)
}

/// [Impersonates the client][imp] of the named pipe.
///
/// The returned impersonation guard automatically reverts impersonation when it goes out of
/// scope.
///
/// [imp]: https://learn.microsoft.com/en-us/windows/win32/api/namedpipeapi/nf-namedpipeapi-impersonatenamedpipeclient
pub fn impersonate_client(&self) -> io::Result<ImpersonationGuard> {
unsafe { Pipes::ImpersonateNamedPipeClient(self.as_int_handle()) }
.to_bool()
.true_or_errno(|| ImpersonationGuard(()))
}
}

0 comments on commit 5bcd669

Please sign in to comment.