Skip to main content

windows_permissions/
windows_secure.rs

1use crate::constants::{SeObjectType::SE_UNKNOWN_OBJECT_TYPE, SecurityInformation};
2use crate::{wrappers, Acl, LocalBox, SecurityDescriptor, Sid};
3use std::ffi::OsStr;
4use std::io;
5use std::os::windows::io::AsRawHandle;
6
7/// A trait indicating that an object is subject to Windows security.
8pub trait WindowsSecure {
9    /// Get a security descriptor for the object
10    fn security_descriptor(
11        &self,
12        sec_info: SecurityInformation,
13    ) -> io::Result<LocalBox<SecurityDescriptor>>;
14
15    /// Set the object's owner
16    fn set_owner(&mut self, owner: &Sid) -> io::Result<()>;
17
18    /// Set the object's group
19    fn set_group(&mut self, group: &Sid) -> io::Result<()>;
20
21    /// Set the object's DACL
22    fn set_dacl(&mut self, dacl: &Acl) -> io::Result<()>;
23
24    /// Set the object's SACL
25    fn set_sacl(&mut self, sacl: &Acl) -> io::Result<()>;
26
27    /// Set multiple security options at once
28    ///
29    /// Some securable objects may be able to set multiple security options at
30    /// the same time with less overhead. The default implementation just calls
31    /// each of the other functions one at a time.
32    ///
33    /// This does not guarantee an atomic update. It is possible that only some
34    /// of the options will be updated.
35    fn set_multiple(
36        &mut self,
37        owner: Option<&Sid>,
38        group: Option<&Sid>,
39        dacl: Option<&Acl>,
40        sacl: Option<&Acl>,
41    ) -> io::Result<()> {
42        if let Some(o) = owner {
43            self.set_owner(o)?
44        }
45
46        if let Some(g) = group {
47            self.set_group(g)?
48        }
49
50        if let Some(d) = dacl {
51            self.set_dacl(d)?
52        }
53
54        if let Some(s) = sacl {
55            self.set_sacl(s)?
56        }
57
58        Ok(())
59    }
60
61    /// Set the object's security descriptor.
62    fn set_security_descriptor(&mut self, sd: &SecurityDescriptor) -> io::Result<()> {
63        self.set_multiple(sd.owner(), sd.group(), sd.dacl(), sd.sacl())
64    }
65}
66
67impl<T> WindowsSecure for T
68where
69    T: AsRawHandle,
70{
71    fn security_descriptor(
72        &self,
73        sec_info: SecurityInformation,
74    ) -> io::Result<LocalBox<SecurityDescriptor>> {
75        wrappers::GetSecurityInfo(self, SE_UNKNOWN_OBJECT_TYPE, sec_info)
76    }
77
78    fn set_owner(&mut self, owner: &Sid) -> io::Result<()> {
79        wrappers::SetSecurityInfo(
80            self,
81            SE_UNKNOWN_OBJECT_TYPE,
82            SecurityInformation::Owner,
83            Some(owner),
84            None,
85            None,
86            None,
87        )
88    }
89
90    fn set_group(&mut self, group: &Sid) -> io::Result<()> {
91        wrappers::SetSecurityInfo(
92            self,
93            SE_UNKNOWN_OBJECT_TYPE,
94            SecurityInformation::Group,
95            None,
96            Some(group),
97            None,
98            None,
99        )
100    }
101
102    fn set_dacl(&mut self, dacl: &Acl) -> io::Result<()> {
103        wrappers::SetSecurityInfo(
104            self,
105            SE_UNKNOWN_OBJECT_TYPE,
106            SecurityInformation::Dacl,
107            None,
108            None,
109            Some(dacl),
110            None,
111        )
112    }
113
114    fn set_sacl(&mut self, sacl: &Acl) -> io::Result<()> {
115        wrappers::SetSecurityInfo(
116            self,
117            SE_UNKNOWN_OBJECT_TYPE,
118            SecurityInformation::Sacl,
119            None,
120            None,
121            None,
122            Some(sacl),
123        )
124    }
125
126    fn set_multiple(
127        &mut self,
128        owner: Option<&Sid>,
129        group: Option<&Sid>,
130        dacl: Option<&Acl>,
131        sacl: Option<&Acl>,
132    ) -> io::Result<()> {
133        let sec_info = owner
134            .map(|_| SecurityInformation::Owner)
135            .unwrap_or_else(SecurityInformation::empty)
136            | group
137                .map(|_| SecurityInformation::Group)
138                .unwrap_or_else(SecurityInformation::empty)
139            | group
140                .map(|_| SecurityInformation::Dacl)
141                .unwrap_or_else(SecurityInformation::empty)
142            | group
143                .map(|_| SecurityInformation::Sacl)
144                .unwrap_or_else(SecurityInformation::empty);
145
146        wrappers::SetSecurityInfo(
147            self,
148            SE_UNKNOWN_OBJECT_TYPE,
149            sec_info,
150            owner,
151            group,
152            dacl,
153            sacl,
154        )
155    }
156}
157
158impl WindowsSecure for OsStr {
159    fn security_descriptor(
160        &self,
161        sec_info: SecurityInformation,
162    ) -> io::Result<LocalBox<SecurityDescriptor>> {
163        wrappers::GetNamedSecurityInfo(&self, SE_UNKNOWN_OBJECT_TYPE, sec_info)
164    }
165
166    fn set_owner(&mut self, owner: &Sid) -> io::Result<()> {
167        wrappers::SetNamedSecurityInfo(
168            self,
169            SE_UNKNOWN_OBJECT_TYPE,
170            SecurityInformation::Owner,
171            Some(owner),
172            None,
173            None,
174            None,
175        )
176    }
177
178    fn set_group(&mut self, group: &Sid) -> io::Result<()> {
179        wrappers::SetNamedSecurityInfo(
180            self,
181            SE_UNKNOWN_OBJECT_TYPE,
182            SecurityInformation::Group,
183            None,
184            Some(group),
185            None,
186            None,
187        )
188    }
189
190    fn set_dacl(&mut self, dacl: &Acl) -> io::Result<()> {
191        wrappers::SetNamedSecurityInfo(
192            self,
193            SE_UNKNOWN_OBJECT_TYPE,
194            SecurityInformation::Dacl,
195            None,
196            None,
197            Some(dacl),
198            None,
199        )
200    }
201
202    fn set_sacl(&mut self, sacl: &Acl) -> io::Result<()> {
203        wrappers::SetNamedSecurityInfo(
204            self,
205            SE_UNKNOWN_OBJECT_TYPE,
206            SecurityInformation::Sacl,
207            None,
208            None,
209            None,
210            Some(sacl),
211        )
212    }
213
214    fn set_multiple(
215        &mut self,
216        owner: Option<&Sid>,
217        group: Option<&Sid>,
218        dacl: Option<&Acl>,
219        sacl: Option<&Acl>,
220    ) -> io::Result<()> {
221        let sec_info = owner
222            .map(|_| SecurityInformation::Owner)
223            .unwrap_or_else(SecurityInformation::empty)
224            | group
225                .map(|_| SecurityInformation::Group)
226                .unwrap_or_else(SecurityInformation::empty)
227            | dacl
228                .map(|_| SecurityInformation::Dacl)
229                .unwrap_or_else(SecurityInformation::empty)
230            | sacl
231                .map(|_| SecurityInformation::Sacl)
232                .unwrap_or_else(SecurityInformation::empty);
233
234        wrappers::SetNamedSecurityInfo(
235            self,
236            SE_UNKNOWN_OBJECT_TYPE,
237            sec_info,
238            owner,
239            group,
240            dacl,
241            sacl,
242        )
243    }
244}