@@ -204,7 +204,7 @@ func (s pipeAddress) String() string {
204
204
}
205
205
206
206
// tryDialPipe attempts to dial the pipe at `path` until `ctx` cancellation or timeout.
207
- func tryDialPipe (ctx context.Context , path * string , access fs.AccessMask ) (windows.Handle , error ) {
207
+ func tryDialPipe (ctx context.Context , path * string , access fs.AccessMask , impLevel PipeImpLevel ) (windows.Handle , error ) {
208
208
for {
209
209
select {
210
210
case <- ctx .Done ():
@@ -215,7 +215,7 @@ func tryDialPipe(ctx context.Context, path *string, access fs.AccessMask) (windo
215
215
0 , // mode
216
216
nil , // security attributes
217
217
fs .OPEN_EXISTING ,
218
- fs .FILE_FLAG_OVERLAPPED | fs .SECURITY_SQOS_PRESENT | fs .SECURITY_ANONYMOUS ,
218
+ fs .FILE_FLAG_OVERLAPPED | fs .SECURITY_SQOS_PRESENT | fs .FileSQSFlag ( impLevel ) ,
219
219
0 , // template file handle
220
220
)
221
221
if err == nil {
@@ -256,12 +256,30 @@ func DialPipeContext(ctx context.Context, path string) (net.Conn, error) {
256
256
return DialPipeAccess (ctx , path , uint32 (fs .GENERIC_READ | fs .GENERIC_WRITE ))
257
257
}
258
258
259
+ // PipeImpLevel is an enumeration of impersonation levels that may be set
260
+ // when calling DialPipeAccessImpersonation.
261
+ type PipeImpLevel uint32
262
+
263
+ const (
264
+ PipeImpLevelAnonymous = PipeImpLevel (fs .SECURITY_ANONYMOUS )
265
+ PipeImpLevelIdentification = PipeImpLevel (fs .SECURITY_IDENTIFICATION )
266
+ PipeImpLevelImpersonation = PipeImpLevel (fs .SECURITY_IMPERSONATION )
267
+ PipeImpLevelDelegation = PipeImpLevel (fs .SECURITY_DELEGATION )
268
+ )
269
+
259
270
// DialPipeAccess attempts to connect to a named pipe by `path` with `access` until `ctx`
260
271
// cancellation or timeout.
261
272
func DialPipeAccess (ctx context.Context , path string , access uint32 ) (net.Conn , error ) {
273
+ return DialPipeAccessImpLevel (ctx , path , access , PipeImpLevelAnonymous )
274
+ }
275
+
276
+ // DialPipeAccessImpLevel attempts to connect to a named pipe by `path` with
277
+ // `access` at `impLevel` until `ctx` cancellation or timeout. The other
278
+ // DialPipe* implementations use PipeImpLevelAnonymous.
279
+ func DialPipeAccessImpLevel (ctx context.Context , path string , access uint32 , impLevel PipeImpLevel ) (net.Conn , error ) {
262
280
var err error
263
281
var h windows.Handle
264
- h , err = tryDialPipe (ctx , & path , fs .AccessMask (access ))
282
+ h , err = tryDialPipe (ctx , & path , fs .AccessMask (access ), impLevel )
265
283
if err != nil {
266
284
return nil , err
267
285
}
0 commit comments