2 * Windows support module which deals with being a named-pipe client.
8 #define DEFINE_PLUG_METHOD_MACROS
15 #if !defined NO_SECURITY
19 Socket
make_handle_socket(HANDLE send_H
, HANDLE recv_H
, Plug plug
,
22 Socket
new_named_pipe_client(const char *pipename
, Plug plug
)
25 PSID usersid
, pipeowner
;
26 PSECURITY_DESCRIPTOR psd
;
30 assert(strncmp(pipename
, "\\\\.\\pipe\\", 9) == 0);
31 assert(strchr(pipename
+ 9, '\\') == NULL
);
34 pipehandle
= CreateFile(pipename
, GENERIC_READ
| GENERIC_WRITE
,
35 0, NULL
, OPEN_EXISTING
,
36 FILE_FLAG_OVERLAPPED
, NULL
);
38 if (pipehandle
!= INVALID_HANDLE_VALUE
)
41 if (GetLastError() != ERROR_PIPE_BUSY
) {
42 err
= dupprintf("Unable to open named pipe '%s': %s",
43 pipename
, win_strerror(GetLastError()));
44 ret
= new_error_socket(err
, plug
);
50 * If we got ERROR_PIPE_BUSY, wait for the server to
51 * create a new pipe instance. (Since the server is
52 * expected to be winnps.c, which will do that immediately
53 * after a previous connection is accepted, that shouldn't
54 * take excessively long.)
56 if (!WaitNamedPipe(pipename
, NMPWAIT_USE_DEFAULT_WAIT
)) {
57 err
= dupprintf("Error waiting for named pipe '%s': %s",
58 pipename
, win_strerror(GetLastError()));
59 ret
= new_error_socket(err
, plug
);
65 if ((usersid
= get_user_sid()) == NULL
) {
66 CloseHandle(pipehandle
);
67 err
= dupprintf("Unable to get user SID");
68 ret
= new_error_socket(err
, plug
);
73 if (p_GetSecurityInfo(pipehandle
, SE_KERNEL_OBJECT
,
74 OWNER_SECURITY_INFORMATION
,
75 &pipeowner
, NULL
, NULL
, NULL
,
76 &psd
) != ERROR_SUCCESS
) {
77 err
= dupprintf("Unable to get named pipe security information: %s",
78 win_strerror(GetLastError()));
79 ret
= new_error_socket(err
, plug
);
81 CloseHandle(pipehandle
);
86 if (!EqualSid(pipeowner
, usersid
)) {
87 err
= dupprintf("Owner of named pipe '%s' is not us", pipename
);
88 ret
= new_error_socket(err
, plug
);
90 CloseHandle(pipehandle
);
99 return make_handle_socket(pipehandle
, pipehandle
, plug
, TRUE
);
102 #endif /* !defined NO_SECURITY */