262 lines
8.8 KiB
Plaintext
262 lines
8.8 KiB
Plaintext
///////////////////////////////////////////////////////////////////////////////
|
|
//
|
|
// Copyright (c) Microsoft Corporation. All rights reserved.
|
|
//
|
|
|
|
/*
|
|
|
|
This file contains contracts and structure definitions for use with the SMB client.
|
|
The most important contract is SmbClientControlContract, which allows processes,
|
|
such as the SMB status / control tool, to query and display the state of an SMB
|
|
client process, and to send control requests to the client process.
|
|
|
|
*/
|
|
|
|
using System;
|
|
using Microsoft.Singularity.Channels;
|
|
using Microsoft.SingSharp;
|
|
using Microsoft.Singularity.Directory;
|
|
|
|
namespace Smb.PublicChannels
|
|
{
|
|
/*
|
|
This contract allows control / management tools to communicate with the
|
|
SMB Client Manager service. The service is a singleton, which manages
|
|
(creates, configures, stops) the SMB client processes (instances of
|
|
SmbClient.exe). The importer of this contract is usually net.exe.
|
|
*/
|
|
public contract SmbClientManagerContract : ServiceContract
|
|
{
|
|
out message Success();
|
|
|
|
override state Start: one {
|
|
Success! -> Ready;
|
|
}
|
|
|
|
in message CreateClient(SmbClientConfig config);
|
|
|
|
in message StopClient(char[]! in ExHeap clientId);
|
|
|
|
in message BindClient(char[]! in ExHeap clientId, ServiceContract.Exp:Start! exp);
|
|
|
|
in message EnumClients();
|
|
out message ClientList(char[][]! in ExHeap clientIdList);
|
|
|
|
out message Ok();
|
|
out message RequestFailed(SmbErrorCode error, char[] in ExHeap errortext);
|
|
|
|
in message QueryClientStatus(char[]! in ExHeap clientId);
|
|
out message ClientStatusReport(SmbClientStatus status);
|
|
|
|
in message QueryClientConfig(char[]! in ExHeap clientId);
|
|
out message ClientConfigReport(SmbClientConfig status);
|
|
|
|
state Ready : one
|
|
{
|
|
CreateClient? -> CreatingClient;
|
|
StopClient? -> (Ok! or RequestFailed!) -> Ready;
|
|
EnumClients? -> (ClientList! or RequestFailed!) -> Ready;
|
|
BindClient? -> (Ok! or RequestFailed!) -> Ready;
|
|
QueryClientStatus? -> (ClientStatusReport! or RequestFailed!) -> Ready;
|
|
QueryClientConfig? -> (ClientConfigReport! or RequestFailed!) -> Ready;
|
|
}
|
|
|
|
state CreatingClient : one {
|
|
Ok! -> Ready;
|
|
RequestFailed! -> Ready;
|
|
}
|
|
|
|
public const string ManagerControlPath = "/dev/smb-client-manager";
|
|
}
|
|
|
|
public enum SmbErrorCode
|
|
{
|
|
Success = 0,
|
|
MountPathAlreadyExists, // a client with the same mount path already exists
|
|
ClientExists,
|
|
AuthorizationDenied,
|
|
MountPathNotFound,
|
|
InternalError,
|
|
InvalidState,
|
|
|
|
}
|
|
|
|
// Each instance of the SMB client process (smbclient.exe) registers an instance of this
|
|
// endpoint, usually as /dev/smb.xxx, where xxx is some arbitrary unique identifier.
|
|
// This contract allows control / management tools, such as smb.exe, to query and display
|
|
// information about running SMB clients, to send control requests to them (e.g. reconnect),
|
|
// and to terminate (unmount) them.
|
|
//
|
|
// Note: This contract will be eliminated, and its equivalent control functions will be moved
|
|
// to SmbClientManagerContract.
|
|
public contract SmbClientControlContract : ServiceContract
|
|
{
|
|
#if false
|
|
// This method polls the status of the client. The status can change
|
|
// over time.
|
|
in message GetStatus();
|
|
out message StatusReport(SmbClientStatus status);
|
|
|
|
// This method polls the configuration of the client. The configuration
|
|
// does not (currently) change over time.
|
|
in message GetConfig();
|
|
out message ConfigReport(SmbClientConfig config);
|
|
#endif
|
|
|
|
// This method requests that the client disconnect from the remote
|
|
// server (if it is connected), terminate all channel service threads,
|
|
// and terminate the process.
|
|
in message Terminate();
|
|
out message AckTerminate();
|
|
|
|
// This method disconnects the client from the remote server.
|
|
// The client does not terminate. If the client receives any
|
|
// requests (from local processes), then the client will attempt
|
|
// to reconnect to the server.
|
|
in message Disconnect();
|
|
out message AckDisconnect();
|
|
|
|
// This method disconnects the client and attempts to reconnect.
|
|
in message Reconnect();
|
|
out message AckReconnect();
|
|
|
|
out message Success();
|
|
|
|
override state Start: one {
|
|
Success! -> Ready;
|
|
}
|
|
|
|
state Ready : one
|
|
{
|
|
#if false
|
|
GetStatus? -> StatusReport! -> Ready;
|
|
GetConfig? -> ConfigReport! -> Ready;
|
|
#endif
|
|
Terminate? -> AckTerminate! -> Terminating;
|
|
Disconnect? -> AckDisconnect! -> Ready;
|
|
Reconnect? -> AckReconnect! -> Ready;
|
|
}
|
|
|
|
state Terminating : one
|
|
{
|
|
}
|
|
}
|
|
|
|
public enum SmbClientConnectionStatus
|
|
{
|
|
Invalid = 0,
|
|
Disconnected, // no activity, so we are not connected
|
|
TransportConnecting, // we're trying to establish connectivity at the transport level (TCP/IP or NBT)
|
|
Negotiating, // transport is connected, now doing SMB negotiation, SESSION SETUP, etc.
|
|
Authenticating, //
|
|
Connected, // connected and ready to use
|
|
}
|
|
|
|
public enum SmbReasonDisconnected
|
|
{
|
|
Invalid = 0,
|
|
Idle, // no one has asked to connect to the server yet
|
|
TransportConnectFailed, // failed to connect
|
|
NegotiationFailed, // SMB-level negotiation failed
|
|
ResourceConnectFailed, // SMB server rejected TreeConnect
|
|
AuthenticationFailed, // failed to prove identity
|
|
AuthorizationFailed, // authenticated, but user is not authorized to use resource
|
|
NoResponse, // no response to transport-level messages; assuming server is dead or unreachable
|
|
ProtocolViolation, // received invalid SMB messages
|
|
TransportFailure, // transport failure of some kind, after successful connection
|
|
}
|
|
|
|
// This structure describes the configuration of the SMB client.
|
|
// It represents the "goal state" of the client.
|
|
// The client will attempt to connect and service SMB requests, using
|
|
// this configuration information. If any errors occur (TCP-level
|
|
// connection failures, authentication failures, etc.), then the
|
|
// client will periodically retry the connection.
|
|
public rep struct SmbClientConfig : ITracked
|
|
{
|
|
public char[]! in ExHeap UncPath; // UNC of resource, such as \\foo\bar
|
|
public char[]! in ExHeap MountPath; // local mount path, e.g. /share, implements DirectoryServiceContract
|
|
public char[]! in ExHeap ControlPath; // local path of SmbClientControlContract, e.g. /dev/smb.xxx
|
|
public char[]! in ExHeap CredentialsName; // auth principal name, e.g. domain\user, user@domain.com, OPTIONAL
|
|
public char[]! in ExHeap Tag; // credentials tag, only set if CredentialsName != null
|
|
}
|
|
|
|
// This structure describes the current status of the SMB client.
|
|
// The status is always sampled as a single snapshot in time, rather
|
|
// than having multiple round-trips to query individual fields.
|
|
public rep struct SmbClientStatus : ITracked
|
|
{
|
|
public SmbClientConnectionStatus ConnectionStatus;
|
|
public SmbReasonDisconnected ReasonDisconnected;
|
|
|
|
// If the client successfully connects to the SMB server, then these values
|
|
// contain information that was received during SMB negotiation. These values
|
|
// are useful for status displays.
|
|
public char[] in ExHeap ServerMachineName;
|
|
public char[] in ExHeap ServerDomainName;
|
|
public char[] in ExHeap ServerOperatingSystem;
|
|
public char[] in ExHeap ActiveCredentialsName;
|
|
}
|
|
|
|
/*
|
|
This contract is used for communication between the SMB Client Manager service
|
|
(SmbClientManager) and instances SMB Client Process (SmbClient). The SMB Client Manager
|
|
service is the only process that creates any instances of the SmbClient executable;
|
|
it uses this contract to control the SmbClient processes. This allows detailed,
|
|
typed configuration information to be conveyed to the SmbClient (rather than relying
|
|
on command-line parameters), and also control messages (stop, etc.).
|
|
|
|
The SmbClient process uses Process.GetStartupEndpoint (at index 0) to bind to its instance
|
|
of SmbClientControllerContract.Exp.
|
|
|
|
The importer of this contract is always SmbClientManager.
|
|
The exporter of this contract is always SmbClient.
|
|
*/
|
|
public contract SmbClientControllerContract
|
|
{
|
|
in message Configure(SmbClientConfig config);
|
|
|
|
in message Bind(ServiceContract.Exp:Start! exp);
|
|
|
|
out message Ok();
|
|
out message RequestFailed(SmbErrorCode error, char[] in ExHeap optionalErrorText);
|
|
|
|
state Created : one
|
|
{
|
|
Configure? -> Configuring;
|
|
}
|
|
|
|
state Configuring : one
|
|
{
|
|
Ok! -> Running;
|
|
RequestFailed! -> Created;
|
|
}
|
|
|
|
in message Stop();
|
|
|
|
state Running : one
|
|
{
|
|
Bind? -> (Ok! or RequestFailed!) -> Running;
|
|
Stop? -> Ok! -> Stopped;
|
|
}
|
|
|
|
state Stopped : one
|
|
{
|
|
}
|
|
}
|
|
|
|
|
|
public contract SmbMuxNotifier
|
|
{
|
|
in message StatusChanged(SmbClientStatus muxstate);
|
|
|
|
out message Ack();
|
|
|
|
state Ready : one
|
|
{
|
|
StatusChanged? -> Ack! -> Ready;
|
|
}
|
|
}
|
|
|
|
}
|