-
Notifications
You must be signed in to change notification settings - Fork 2
/
server.go
274 lines (262 loc) · 16.4 KB
/
server.go
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
package witness
import (
"context"
"fmt"
"strings"
"unicode/utf16"
dcerpc "github.com/oiweiwei/go-msrpc/dcerpc"
errors "github.com/oiweiwei/go-msrpc/dcerpc/errors"
uuid "github.com/oiweiwei/go-msrpc/midl/uuid"
ndr "github.com/oiweiwei/go-msrpc/ndr"
)
var (
_ = context.Background
_ = fmt.Errorf
_ = utf16.Encode
_ = strings.TrimPrefix
_ = ndr.ZeroString
_ = (*uuid.UUID)(nil)
_ = (*dcerpc.SyntaxID)(nil)
_ = (*errors.Error)(nil)
)
// Witness server interface.
type WitnessServer interface {
// The WitnessrGetInterfaceList method returns information about the interfaces to which
// witness client connections can be made.
//
// Return Values: Returns 0x00000000 (ERROR_SUCCESS) on success or a nonzero error code,
// as specified in [MS-ERREF] section 2.2. The most common error codes are listed in
// the following table.
//
// +------------------------------------+--------------------------------------------------------------+
// | RETURN | |
// | VALUE/CODE | DESCRIPTION |
// | | |
// +------------------------------------+--------------------------------------------------------------+
// +------------------------------------+--------------------------------------------------------------+
// | 0x00000000 ERROR_SUCCESS | The operation completed successfully. |
// +------------------------------------+--------------------------------------------------------------+
// | 0x00000005 ERROR_ACCESS_DENIED | Access is denied. |
// +------------------------------------+--------------------------------------------------------------+
// | 0x00000057 ERROR_INVALID_PARAMETER | The parameter is incorrect. |
// +------------------------------------+--------------------------------------------------------------+
// | 0x00000103 ERROR_NO_MORE_ITEMS | No more data is available. |
// +------------------------------------+--------------------------------------------------------------+
// | 0x0000000E ERROR_OUTOFMEMORY | There is not enough storage space to complete the operation. |
// +------------------------------------+--------------------------------------------------------------+
//
// If there are no entries in the InterfaceList, the server MUST fail the request and
// return the error code ERROR_NO_MORE_ITEMS.
//
// If no entry in the InterfaceList has a State of AVAILABLE, the server MUST wait until
// at least one entry enters that State, as specified in section 3.1.6.1.
//
// For each Interface in the InterfaceList, the server MUST construct a WITNESS_INTERFACE_INFO
// structure as follows:
//
// * The *InterfaceGroupName* field of the WITNESS_INTERFACE_INFO structure MUST be
// set to *Interface.InterfaceGroupName*.
//
// * The *State* field MUST be set to *Interface.State*.
//
// * The *Version* field MUST be set to *WitnessServiceVersion*.
//
// * If *Interface.IPv4Address* is not empty, the *IPV4* field MUST be set to *Interface.IPv4Address*
// , and IPv4 flag MUST be set in the *Flags* field.
//
// * If *Interface.IPv6Address* is not empty, the *IPV6* field MUST be set to *Interface.IPv6Address*
// , and IPv6 flag MUST be set in the *Flags* field.
//
// * In an implementation-dependent manner, the server MUST determine if the *IPv4Address*
// or *IPv6Address* match any interface which is hosted on the server and the server
// is also running this Witness Service instance. If the address is not hosted on the
// local server, the INTERFACE_WITNESS flag MUST be set in the *Flags* field. Otherwise,
// the flag MUST NOT be set.
GetInterfaceList(context.Context, *GetInterfaceListRequest) (*GetInterfaceListResponse, error)
// The WitnessrRegister method allows the witness client to register for resource state
// change notifications of a NetName and IPAddress. The client can subsequently call
// the WitnessrAsyncNotify method to receive notifications when there is a state change
// on any of these resources.
//
// Return Values: Returns 0x00000000 (ERROR_SUCCESS) on success or a nonzero error code,
// as specified in [MS-ERREF] section 2.2. The most common error codes are listed in
// the following table.
//
// +--------------------------------------+------------------------------------------------------------------------+
// | RETURN | |
// | VALUE/CODE | DESCRIPTION |
// | | |
// +--------------------------------------+------------------------------------------------------------------------+
// +--------------------------------------+------------------------------------------------------------------------+
// | 0x00000000 ERROR_SUCCESS | The operation completed successfully. |
// +--------------------------------------+------------------------------------------------------------------------+
// | 0x00000005 ERROR_ACCESS_DENIED | Access is denied. |
// +--------------------------------------+------------------------------------------------------------------------+
// | 0x000005AA ERROR_NO_SYSTEM_RESOURCES | Insufficient system resources exist to complete the requested service. |
// +--------------------------------------+------------------------------------------------------------------------+
// | 0x00000057 ERROR_INVALID_PARAMETER | The parameter is incorrect. |
// +--------------------------------------+------------------------------------------------------------------------+
// | 0x0000139F ERROR_INVALID_STATE | The specified resource state is invalid. |
// +--------------------------------------+------------------------------------------------------------------------+
// | 0x0000051A ERROR_REVISION_MISMATCH | The client request contains an invalid Witness protocol version. |
// +--------------------------------------+------------------------------------------------------------------------+
//
// If the Version field of the request is not 0x00010001, the server MUST stop processing
// the request and return the error code ERROR_REVISION_MISMATCH.
//
// If NetName, IpAddress or ClientComputerName is NULL, the server MUST fail the request
// and return the error code ERROR_INVALID_PARAMETER.
//
// If the NetName parameter is not equal to ServerGlobalName, the server MUST fail the
// request and return the error code ERROR_INVALID_PARAMETER.
Register(context.Context, *RegisterRequest) (*RegisterResponse, error)
// The WitnessrUnRegister method allows the client to unregister for notifications from
// the server. The Witness Service removes its internal state of the registration and
// no longer notifies the client in the event of any resource state changes.
//
// Return Values: Returns 0x00000000 (ERROR_SUCCESS) on success or a nonzero error code,
// as specified in [MS-ERREF] section 2.2. The most common error codes are listed in
// the following table.
//
// +--------------------------------+--------------------------------------------+
// | RETURN | |
// | VALUE/CODE | DESCRIPTION |
// | | |
// +--------------------------------+--------------------------------------------+
// +--------------------------------+--------------------------------------------+
// | 0x00000000 ERROR_SUCCESS | The operation completed successfully. |
// +--------------------------------+--------------------------------------------+
// | 0x00000005 ERROR_ACCESS_DENIED | Access is denied. |
// +--------------------------------+--------------------------------------------+
// | 0x00000490 ERROR_NOT_FOUND | The specified CONTEXT_HANDLE is not found. |
// +--------------------------------+--------------------------------------------+
Unregister(context.Context, *UnregisterRequest) (*UnregisterResponse, error)
// The WitnessrAsyncNotify method is used by the client to request notification of registered
// resource changes from the server.
//
// Return Values: Returns 0x00000000 (ERROR_SUCCESS) on success or a nonzero error code,
// as specified in [MS-ERREF] section 2.2. The most common error codes are listed in
// the following table.
//
// +--------------------------------------+------------------------------------------------------------------------+
// | RETURN | |
// | VALUE/CODE | DESCRIPTION |
// | | |
// +--------------------------------------+------------------------------------------------------------------------+
// +--------------------------------------+------------------------------------------------------------------------+
// | 0x00000000 ERROR_SUCCESS | The operation completed successfully. |
// +--------------------------------------+------------------------------------------------------------------------+
// | 0x00000005 ERROR_ACCESS_DENIED | Access is denied. |
// +--------------------------------------+------------------------------------------------------------------------+
// | 0x000005AA ERROR_NO_SYSTEM_RESOURCES | Insufficient system resources exist to complete the requested service. |
// +--------------------------------------+------------------------------------------------------------------------+
// | 0x00000490 ERROR_NOT_FOUND | The specified resource name is not found. |
// +--------------------------------------+------------------------------------------------------------------------+
AsyncNotify(context.Context, *AsyncNotifyRequest) (*AsyncNotifyResponse, error)
// The WitnessrRegisterEx method allows the witness client to register for resource
// state change notifications of a NetName, ShareName and multiple IPAddresses. The
// client can subsequently call the WitnessrAsyncNotify method to receive notifications
// when there is a state change on any of these resources.
//
// Return Values: Returns 0x00000000 (ERROR_SUCCESS) on success or a nonzero error code,
// as specified in [MS-ERREF] section 2.2. The most common error codes are listed in
// the following table.
//
// +--------------------------------------+------------------------------------------------------------------------+
// | RETURN | |
// | VALUE/CODE | DESCRIPTION |
// | | |
// +--------------------------------------+------------------------------------------------------------------------+
// +--------------------------------------+------------------------------------------------------------------------+
// | 0x00000000 ERROR_SUCCESS | The operation completed successfully. |
// +--------------------------------------+------------------------------------------------------------------------+
// | 0x00000005 ERROR_ACCESS_DENIED | Access is denied. |
// +--------------------------------------+------------------------------------------------------------------------+
// | 0x000005AA ERROR_NO_SYSTEM_RESOURCES | Insufficient system resources exist to complete the requested service. |
// +--------------------------------------+------------------------------------------------------------------------+
// | 0x00000057 ERROR_INVALID_PARAMETER | The parameter is incorrect. |
// +--------------------------------------+------------------------------------------------------------------------+
// | 0x0000139F ERROR_INVALID_STATE | The specified resource state is invalid. |
// +--------------------------------------+------------------------------------------------------------------------+
// | 0x0000051A ERROR_REVISION_MISMATCH | The client request contains an invalid Witness protocol version. |
// +--------------------------------------+------------------------------------------------------------------------+
//
// This opnum is applicable only to servers that implement Witness protocol version
// 2.
//
// If the Version field of the request is not 0x00020000, the server MUST stop processing
// the request and return the error code ERROR_REVISION_MISMATCH.
//
// If NetName, IpAddress, or ClientComputerName is NULL, the server MUST fail the request
// and return the error code ERROR_INVALID_PARAMETER.
//
// If the NetName parameter is not equal to ServerGlobalName, the server MUST fail the
// request and return the error code ERROR_INVALID_PARAMETER.
//
// If ShareName is not NULL, the server MUST enumerate the shares by calling NetrShareEnum
// as specified in [MS-SRVS] section 3.1.4.8. If the enumeration fails or if no shares
// are returned, the server MUST return the error code ERROR_INVALID_STATE.
//
// If none of the shares in the list has shi*_type set to STYPE_CLUSTER_SOFS as specified
// in [MS-SRVS] section 3.1.4.8, the server MUST ignore ShareName.
//
// Otherwise, the server MUST fail the request with the error code ERROR_INVALID_STATE
// for the following:
//
// * *ShareName* does not exist in the enumerated list.
//
// * The server MUST search for an *Interface* in *InterfaceList* , where *Interface.IPv4Address*
// or *Interface.IPv6Address* matches the IpAddress parameter based on its format. If
// no matching entry is found and *ShareName* has shi*_type set to STYPE_CLUSTER_SOFS,
// as specified in [MS-SRVS] section 2.2.2.4 ( ../ms-srvs/6069f8c0-c93f-43a0-a5b4-7ed447eb4b84
// ) , the server MUST fail the request with ERROR_INVALID_STATE. **
RegisterEx(context.Context, *RegisterExRequest) (*RegisterExResponse, error)
}
func RegisterWitnessServer(conn dcerpc.Conn, o WitnessServer, opts ...dcerpc.Option) {
conn.RegisterServer(NewWitnessServerHandle(o), append(opts, dcerpc.WithAbstractSyntax(WitnessSyntaxV1_1))...)
}
func NewWitnessServerHandle(o WitnessServer) dcerpc.ServerHandle {
return func(ctx context.Context, opNum int, r ndr.Reader) (dcerpc.Operation, error) {
return WitnessServerHandle(ctx, o, opNum, r)
}
}
func WitnessServerHandle(ctx context.Context, o WitnessServer, opNum int, r ndr.Reader) (dcerpc.Operation, error) {
switch opNum {
case 0: // WitnessrGetInterfaceList
in := &GetInterfaceListRequest{}
if err := in.UnmarshalNDR(ctx, r); err != nil {
return nil, err
}
resp, err := o.GetInterfaceList(ctx, in)
return resp.xxx_ToOp(ctx), err
case 1: // WitnessrRegister
in := &RegisterRequest{}
if err := in.UnmarshalNDR(ctx, r); err != nil {
return nil, err
}
resp, err := o.Register(ctx, in)
return resp.xxx_ToOp(ctx), err
case 2: // WitnessrUnRegister
in := &UnregisterRequest{}
if err := in.UnmarshalNDR(ctx, r); err != nil {
return nil, err
}
resp, err := o.Unregister(ctx, in)
return resp.xxx_ToOp(ctx), err
case 3: // WitnessrAsyncNotify
in := &AsyncNotifyRequest{}
if err := in.UnmarshalNDR(ctx, r); err != nil {
return nil, err
}
resp, err := o.AsyncNotify(ctx, in)
return resp.xxx_ToOp(ctx), err
case 4: // WitnessrRegisterEx
in := &RegisterExRequest{}
if err := in.UnmarshalNDR(ctx, r); err != nil {
return nil, err
}
resp, err := o.RegisterEx(ctx, in)
return resp.xxx_ToOp(ctx), err
}
return nil, nil
}