1.概念
samba是运行于unix/linux的软件。它分为服务器端和客户端,实现了cifs协议描述的功能。用于windows和unix/linux见文件共享
cifs:Windows上的文件共享协议,其前身是smb协议
2.协议详解
2.1 cifs协议头格式
0 |
1 |
2 |
3 |
4 |
5 |
6 |
7 |
0 |
1 |
2 |
3 |
4 |
5 |
6 |
7 |
0 |
1 |
2 |
3 |
4 |
5 |
6 |
7 |
0 |
1 |
2 |
3 |
4 |
5 |
6 |
7 |
0xFF |
'S' |
'M' |
'B' | ||||||||||||||||||||||||||||
Command |
Error class |
Must be zero |
Error code | ||||||||||||||||||||||||||||
Error code(continued) |
Flags |
Flags2 | |||||||||||||||||||||||||||||
填充或者安全签名,通常标准的填充是0 | |||||||||||||||||||||||||||||||
树ID(TID) |
进程ID(PID) | ||||||||||||||||||||||||||||||
用户ID(UID) |
多重识别码(MID) | ||||||||||||||||||||||||||||||
wordcount |
Parameterwords[wordcount] | ||||||||||||||||||||||||||||||
| |||||||||||||||||||||||||||||||
Bytecount |
| ||||||||||||||||||||||||||||||
Buffer[bytecount] |
Command:cifs命令,表明这包数据的作用
Error class Error code:错误类型和错误代码
Flash Flags2:表示服务器或者客户端的限制
TID:用来标识这个CIFS数据包指的是什么资源(通常为磁盘共享或者打印机)。当数据包交换没有牵涉到某个资源
时,这个域是无意义的,可以忽略的。
PID:用来标识客户端上的哪个进程发出的CIFS请求。服务器使用这个数字来检查并发问题(通常是为了保证文件不会被竞争中的客户端进程所损坏)
UID:用来标识在客户端发出CIFS请求的用户。客户端必须发送一个包含用户名和密码的CIFS数据包请求来获得服务器给定的UID。服务器在验证了用户名和密码之后会应答该请求,该应答中包含一个服务器生成的UID
MID:用来标示一对请求和应答
wordcount,parameterwords:参数域,用来表示命令的具体参数数据。Wordcount域实际表明parameterwords域的长度(以2字节为单位)。
Bytecount,Buffer:缓冲区,类似于参数域,不同在于,参数域通常包含少量的数据包命令参数选项,而缓冲区包含大量的原始数据(如共享文件中的数据)。
2.2 cifs的command主要有下面这些
SMB_COM_CREATE_DIRECTORY (0x00)
不推荐使用。客户程序应该使用TRANS2_CREATE_DIRECTORY替代。
创建目录命令用来在连接的共享服务器上建立一个新的目录。客户端必须提供一个有效的UID和TID,以及需要创建的目录的名称(相对于TID)。
为了新建一个目录,服务器要求客户端至少提供子目录的创建权限。创建者对新建目录的存取权限有服务器的本地策略决定。
SMB_COM_DELETE_DIRECTORY (0x01)
这是原始核心协议的一个命令,用来删除一个空的目录。
SMB_COM_OPEN (0x02)
不推荐使用。客户程序应该使用SMB_COM_NT_CREATE_ANDX替代。
此命令用来打开一个已存在的常规文件,不能用来打开目录文件或命名管道文件。命令携带了客户端想要打开的文件的路径名称。如果命令执行成功,服务器的响应报文中必须携带此文件的标识符FID,客户端在后续的对此文件的操作命令中也必须携带相同的FID。
SMB_COM_CREATE (0x03)
不推荐使用。客户程序应该使用SMB_COM_NT_CREATE_ANDX替代。
此命令用来创建并打开一个新文件,或打开一个已存在的文件并将其内容清空。返回的FID在后续对此文件的操作命令中使用,比如读、写、锁、解锁和关闭。这个命令不能被用来创建目录或命名管道。命令请求中携带了需要创建的文件名及其路径。如果命令执行成功,服务器的响应命令中必须携带FID,客户端在后续对此文件的操作命令中也必须携带相同的FID。客户端必须拥有对文件父目录的写权限,才能在其中新建文件;或对文件本身具有写权限,才能清空文件内容。客户端对新建的文件的访问权限必须是读和写。如果文件原来已存在,只是打开后清空其内容,原来的访问权限保持不变。文件以读/写/兼容模式打开。
SMB_COM_CLOSE (0x04)
用来关闭和一个有效的FID关联的对象的一个实例。
SMB_COM_FLUSH (0x05)
用来要求服务器将当前文件的所有数据和信息都写回到存储器上。
SMB_COM_DELETE (0x06)
用来删除一个或多个常规文件。支持文件名中有通配符,允许一次删除多个文件。
SMB_COM_RENAME (0x07)
用来重命名一个或多个文件或目录。允许文件名中有通配符,允许一次修改多个文件的文件名
SMB_COM_QUERY_INFORMATION (0x08)
不推荐使用。客户程序应该使用SMB_COM_TRANSACTION2的子命令TRANS2_QUERY_PATH_INFORMATION来替代。
客户端可以用这个命令来获取服务器上某个文件的属性信息,前提是提供文件名和路径,不需要提供FID。
SMB_COM_SET_INFORMATION (0x09)
不推荐使用。客户程序应该使用SMB_COM_TRANSACTION2的子命令TRANS2_SET_PATH_INFORMATION来替代。
客户端可以用这个命令来改变一个常规文件或目录的属性。文件名不可以包含通配符,必须使用全名,所有的参数都是可选的。如果服务器不识别某个参数,必须忽略它。如果LastWriteTime字段包含0x00000000,文件的LastWriteTime必须不能改变。
SMB_COM_READ (0x0A)
不推荐使用。客户程序应该使用SMB_COM_READ_ANDX命令来替代。
此命令用来从一个普通文件中读取数据。如果客户端和服务器协商可以支持命名管道或直接读取设备,也可以从其中读取数据。如果服务器返回的字节数比客户端要求的少,表示已经读到文件末尾。如果读取请求的起始地址在或超过了文件尾部,返回0字节。如果要求读取的字节数超过了SMB连接规定的最大字节数MaxBufferSize,服务器必须终止此连接,因为只能支持最大32-bit位移的客户请求,不适合拥有超过32-bit大小的文件。客户端最少要拥有文件的读权限。
SMB_COM_WRITE (0x0B)
不推荐使用。客户程序应该使用SMB_COM_WRITE_ANDX命令来替代。在LAN Manager 1.0 中,引入了对命名管道和I/O设备的支持。
此命令用来向普通文件中写入数据。如果客户端和服务器协商支持命名管道、邮箱或直接读取设备,这个命令也可向这些设备中写入数据。命令也可以用来截断或延长文件到某一指定位置。请求命令中必须包含合法的TID和FID。这个命令最大支持32-bit长度的文件,不适合更大的文件,如果要对大文件进行操作,需要使用命令SMB_COM_WRITE_ANDX。
当FID指示操作的文件是一个硬盘文件,而指定的写入起始偏移量(WriteOffsetInBytes)超过了当前文件的结尾时,文件必须被扩充,文件原来尾部到要求的偏移量之间数据都初始化为0x00。如果指定写入的数据长度(CountOfBytesToWrite)为0x0000,文件将被截断(或扩充)到偏移量的位置。
客户端必须最少要拥有文件的写权限。
SMB_COM_LOCK_BYTE_RANGE (0x0C)
不推荐使用。客户程序应该使用SMB_COM_LOCKING_ANDX命令来替代。
此命令不适用于长度超过32-bit的文件。在LAN Manager 1.0引入的命令SMB_COM_LOCKING_ANDX支持长度超过32-bit的文件,最大支持64-bit长度。SMB_COM_LOCKING_ANDX是LAN Manager 1.0版本以后的客户端进行锁/解锁一段数据的首选。如果客户端需要支持64-bit长度的文件,必须使用NT LAN Manage或以后的版本。
此命令用来锁定一个打开的普通文件中一段连续的数据。支持锁定任一指定文件中任意多的数据段,前提是这些数据段没有重叠的部分。锁定可以防止其他客户或PID对锁定的数据段进行锁定、读和写操作。如果锁定的数据段之间有重叠的部分,必须返回失败,错误码为STATUS_LOCK_NOT_GRANTED (ERRDOS/ERRlock)。锁定的范围可以超出文件大小,但是不会引起文件大小的扩充。只有加锁的进程才可以对其进行解锁。
因为此请求只支持最大32-bit的offset,所以对于大于32-bit的文件不适用。客户端必须至少有文件的读权限。
SMB_COM_UNLOCK_BYTE_RANGE (0x0D)
不推荐使用。客户程序应该使用SMB_COM_LOCKING_ANDX命令来替代。
此命令不适用于长度超过32-bit的文件。在LAN Manager 1.0引入的命令SMB_COM_LOCKING_ANDX支持长度超过32-bit的文件,最大支持64-bit长度。SMB_COM_LOCKING_ANDX是LAN Manager 1.0版本以后的客户端进行锁/解锁一段数据的首选。如果客户端需要支持64-bit长度的文件,必须使用NT LAN Manage或以后的版本。
此命令用来解锁一个打开的普通文件中一段连续的数据。指定的数据段范围必须和先前加锁的范围完全一致,并且是由同一CIFS客户端和进程所加的锁,FID和PID也必须一致。对未加锁的数据进行解锁将被作为一个错误操作。
如果服务器没有立即(200-300毫秒内)同意对指定数据段范围进行解锁,必须返回一个错误给客户端。此命令只支持最大32-bit的文件,不适用大于32-bit的文件。客户端必须最少拥有文件的读权限。
SMB_COM_CREATE_NEW (0x0F)
不推荐使用。客户程序应该使用SMB_COM_NT_CREATE_ANDX命令来替代。
此命令用来创建一个新文件。不能截断或覆盖一个已存在的文件,如果请求的文件已经存在,返回失败。此命令不能用来创建目录或命名管道。
请求消息中包含了路径名(原句:The request message includes the pathname of the file relative to the supplied TID that the client requests to create.),如果执行成功,服务器返回一个FID,在后续的read、write、lock、unlock和close操作中,客户端必须提供相同的FID。客户端必须有文件所在目录的写权限,对新建的文件拥有读写权限。文件以读写兼容模式打开。服务器对客户端提供的创建时间CreationTime(见2.2.4.16.1)的支持是可选的。
SMB_COM_CHECK_DIRECTORY (0x10)
此命令用来检查指定的路径是否在服务器上存在。
SMB_COM_LOCK_AND_READ (0x13)
此命令已废弃。客户端应该使用SMB_COM_LOCKING_ANDX来替代。
此命令用来锁定并读取一段常规文件中的数据。数据段首先被锁定,然后被读取。锁类型是排他性的读/写锁。如果服务器不能立即锁定数据段,要返回给客户端错误。如果没有获取到锁,服务器不应该再去读数据。
如果服务器返回的数据比请求的少,说明文件已经到末尾了。如果文件从文件末尾或者超过文件末尾的位置读取,将会返回0字节。如果请求的字节数超过SMB连接中标记的MaxBufferSize大小,服务器会中断此连接。此命令只适用于文件大小小于32-bit的情况。客户端必须最少拥有文件的读权限。
SMB_COM_WRITE_AND_UNLOCK (0x14)
此命令已废弃。客户端应该使用SMB_COM_LOCKING_ANDX来替代。
此命令用来向文件中写入一段数据并解锁数据。通常用在SMB_COM_LOCK_AND_READ之后,作用在同一文件的同一数据段。服务器的响应消息中用ByteCountWritten来指示实际写入的字节数。
除了不能处理0字节长度的写操作外,此命令和SMB_COM_UNLOCK+ SMB_COM_WRITE命令组合具有相同的作用。对此命令的支持是可选的,如果支持,服务器应该在SMB_COM_NEGOTIATE 命令的响应消息中,将SMB Header的Flag字段的bit 0设为1。如果消息长度超过了TID指定的MaxBufferSize(原句:If the command sends a message of length greater than the MaxBufferSize for the TID specified),服务器可以中断此连接。如果写数据过程中发生了错误,数据保持锁状态。
此命令只支持最大32-bit大小的文件,如果需要支持64-bit大小的文件,客户端应该使用SMB_COM_WRITE_ANDX命令。
如果FID指示此文件是一个磁盘文件并且写入数据的范围超过了文件大小,文件会被扩充。文件末尾到指定的offset之间填充0x00。如果要求写入的字节数为0,不论指定offset是多少,文件大小都不会改变,既不会截断也不会扩充。
客户端必须最少拥有文件的写权限
SMB_COM_READ_RAW (0x1A)
此命令已废弃。客户端应该使用SMB_COM_READ_ANDX来替代。
如果服务器支持此命令,会在SMB_COM_NEGOTIATE命令的响应消息中设置CAP_RAW_MODE capabilities bit。
SMB_COM_WRITE_RAW (0x1D)
此命令已废弃。客户端应该使用SMB_COM_WRITE_ANDX来替代。
服务器对此命令的支持是可选的。如果支持,需要在协议协商过程中将CAP_RAW_MODE相应bit置位。
这是一个专门用于向打开的普通文件、命名管道、设备或后台中写入大量数据的命令。此命令允许客户通过SMB传输大量的未格式化的数据(原始字节),而不用普通的SMB请求格式。也允许客户端发送超过session启动时规定最大buffer大小的消息。
服务器必须可以接收最多65535字节的原始数据。也必须允许客户端的SMB_COM_WRITE_RAW请求中包含一个非格式化的消息。客户端可能会使用此命令发送要写入数据的一部分。
SMB_COM_SET_INFORMATION2 (0x22)
已被废弃。新的客户端应当使用SMB_COM_TRANSACTION2的子命令TRANS2_SET_FILE_INFORMATION来替代。
此命令可以被客户端用来设置服务器上一个打开文件的属性。客户端要在SMB头部提供一个有效的FID。这个FID由前面成功打开文件的命令获得。客户端必须最少拥有文件的写权限。目标文件的属性将按照请求更新。如果请求中的date或time为0,表明服务器不要修改文件的这两个属性。和SMB_COM_SET_INFORMATION(2.2.4.10)相比,此命令允许客户端设置更多的文件属性。
SMB_COM_QUERY_INFORMATION2 (0x23)
已被废弃。新的客户端应当使用SMB_COM_TRANSACTION2的子命令TRANS2_QUERY_FILE_INFORMATION来替代。
此命令可以被客户端用来获取服务器上一个打开文件的属性。客户端在请求消息中必须提供合法的FID。这个FID由前面成功打开文件的命令获得。和SMB_COM_QUERY_INFORMATION相比,此命令允许客户端获取更多的文件属性。服务器只能提供最大32-bit的文件的属性。
SMB_COM_LOCKING_ANDX (0x24)
此命令在LAN Manager 1.0中引入,不适用大于32-bit的文件。支持最大64-bit的实现在NT LAN Manager中引入。
此命令用来锁定一个普通文件中一段连续的数据。支持锁定任一指定文件中任意多的数据段,前提是这些数据段没有重叠的部分。锁定可以防止其他进程使用一个独立的文件句柄(FID)对文件锁定部分进行锁、读和写操作。任何进程使用获取锁的文件的FID都可以访问被锁定的数据(原句:Locks prevent attempts to lock, read, or write the locked portion of the file by other processes using a separate file handle
(FID). Any process using the same FID specified in the request that obtained the lock has access to the locked bytes.)
此命令也可以被服务器用来发送一个OpLock中断通知消息给客户端,客户端收到后发送确认消息。这是CIFS协议中服务器发送请求消息的一个例子。
下面列举的是SMB_COM_LOCKING_ANDX后可能发送的命令
· SMB_COM_CLOSE
· SMB_COM_FLUSH
· SMB_COM_LOCKING_ANDX
· SMB_COM_READ
· SMB_COM_READ_ANDX
· SMB_COM_WRITE
· SMB_COM_WRITE_ANDX
SMB_COM_TRANSACTION (0x25)
此命令在LAN Manager 1.0中引入。
此命令为事务处理协议的传输子协议服务。这些命令可以用于CIFS文件系统内部通信的邮箱和命名管道。如果出书的数据超过了会话建立时规定的MaxBufferSize,必须使用SMB_COM_TRANSACTION_SECONDARY命令来传输超出的部分:SMB_Data.Trans_Data 和 SMB_Data.Trans_Parameter。这两部分在初始化消息中没有固定。
如果客户端没有发送完所有的SMB_Data.Trans_Data,会将DataCount设置为小于TotalDataCount的一个值。同样的,如果SMB_Data.Trans_Parameters没有发送完,会设置ParameterCount为一个小于TotalParameterCount的值。参数部分优先级高于数据部分,客户端在每个消息中应该尽量多的发送数据。服务器应该可以接收无序到达的SMB_Data.Trans_Parameters 和 SMB_Data.Trans_Data,不论是大量还是少量的数据。
在请求和响应消息中,SMB_Data.Trans_Parameters和SMB_Data.Trans_Data的位置和长度都是由SMB_Parameters.ParameterOffset、SMB_Parameters.ParameterCount, SMB_Parameters.DataOffset和SMB_Parameters.DataCount决定。另外需要说明的是,SMB_Parameters.ParameterDisplacement和SMB_Parameters.DataDisplacement可以用来改变发送数据段的序号。服务器应该优先发送SMB_Data.Trans_Parameters。客户端应该准备好组装收到的SMB_Data.Trans_Parameters和SMB_Data.Trans_Data,即使它们是乱序到达的。
SMB_COM_TRANSACTION_SECONDARY (0x26)
此命令在LAN Manager 1.0中引入。
此命令用来完成SMB_COM_TRANSACTION中未传输完毕数据的传输。
在请求和响应消息中,SMB_Data.Trans_Parameters和SMB_Data.Trans_Data的位置和长度都是由SMB_Parameters.ParameterOffset、SMB_Parameters.ParameterCount, SMB_Parameters.DataOffset和SMB_Parameters.DataCount决定。另外需要说明的是,SMB_Parameters.ParameterDisplacement和SMB_Parameters.DataDisplacement可以用来改变发送数据段的序号。服务器应该优先发送SMB_Data.Trans_Parameters。客户端应该准备好组装收到的SMB_Data.Trans_Parameters和SMB_Data.Trans_Data,即使它们是乱序到达的。
SMB_COM_ECHO (0x2B)
此命令在LAN Manager 1.0中引入。
客户端发送此命令测试和服务器的传输层连接。
SMB_COM_WRITE_AND_CLOSE (0x2C)
已被废弃。客户端应该使用SMB_COM_WRITE_ANDX命令替代。
此命令用来向指定的FID的文件写入一段数据并关闭文件。和SMB_COM_WRITE+ SMB_COM_CLOSE组合具有相同的功能。详细情况请查看SMB_COM_WRITE和SMB_COM_CLOSE命令。命令支持两种请求格式:一种6个参数,另一种12个参数。
此命令只支持最大32-bit大小的文件,客户端应该使用SMB_COM_WRITE_ANDX以支持最大64-bit大小的文件。
客户端至少要拥有文件的写权限。如果在写文件到磁盘过程中出错,服务器应该关闭文件。
SMB_COM_OPEN_ANDX (0x2D)
此命令在LAN Manager 1.0中引入。
此命令用来创建并打开一个文件,或者打开一个已存在的普通文件,并执行命令链中的命令。命令链详情见3.2.4.1.1,命令中包含客户端要打开的文件名,命名管道或设备。如果执行成功,服务器响应消息中要携带一个合法的FID。客户端在后续对此文件的操作请求中要提供相同的FID。
下面这些命令是可以放在SMB_COM_OPEN_ANDX命令的AndX链中:
· SMB_COM_READ
· SMB_COM_READ_ANDX
· SMB_COM_IOCTL
· SMB_COM_NO_ANDX_COMMAND
SMB_COM_READ_ANDX (0x2E)
此命令在LAN Manager 1.0中引入,在NT LAN Manager中对其进行了扩展。
此命令用来读取数据,可以读取普通文件,命名管道,或直接访问设别,比如串口(COM)或打印机接口(LPT)。如果客户端用NT LAN Manager或以后的版本协商,应该发送带有12个参数的请求,这个版本支持最大64-bit的文件。此命令是唯一一个支持读取64-bit大小文件的读取命令。
下面这些命令是可以放在SMB_COM_READ_ANDX命令的AndX链中:
· SMB_COM_CLOSE
SMB_COM_WRITE_ANDX (0x2F)
此命令在LAN Manager 1.0中引入。
此命令用来向普通文件,命名管道,或直接访问设别,比如串口(COM)或打印机接口(LPT)中写入数据。如果客户端用NT LAN Manager或以后的版本协商,应该发送带有14个参数的请求,这个版本支持最大64-bit的文件。此命令是唯一一个支持写64-bit大小文件的读取命令。
下面这些命令是可以放在SMB_COM_WRITE_ANDX命令的AndX链中:
· SMB_COM_READ
· SMB_COM_READ_ANDX
· SMB_COM_LOCK_AND_READ
· SMB_COM_CLOSE
SMB_COM_TRANSACTION2 (0x32)
此命令在LAN Manager 1.2中引入。
此子命令支持服务器文件系统更丰富的语义集。允许客户端设置和获取扩展的key/value属性对,支持长文件名(比原始的8.3名字格式要长),可以执行目录搜索及其他任务。
如果客户端没有发送完所有的SMB_Data.Trans_Data,会将DataCount设置为小于TotalDataCount的一个值。同样的,如果SMB_Data.Trans_Parameters没有发送完,会设置ParameterCount为一个小于TotalParameterCount的值。参数部分优先级高于数据部分,客户端在每个消息中应该尽量多的发送数据。服务器应该可以接收无序到达的SMB_Data.Trans_Parameters 和 SMB_Data.Trans_Data,不论是大量还是少量的数据。
在请求和响应消息中,SMB_Data.Trans2_Parameters和SMB_Data.Trans2_Data的位置和长度都是由SMB_Parameters.ParameterOffset、SMB_Parameters.ParameterCount, SMB_Parameters.DataOffset和SMB_Parameters.DataCount决定。另外需要说明的是,SMB_Parameters.ParameterDisplacement和SMB_Parameters.DataDisplacement可以用来改变发送数据段的序号。服务器应该优先发送SMB_Data.Trans2_Parameters。客户端应该准备好组装收到的SMB_Data.Trans2_Parameters和SMB_Data.Trans2_Data,即使它们是乱序到达的。
SMB_COM_TRANSACTION2_SECONDARY (0x33)
此命令在LAN Manager 1.2中引入。
此命令用来完成SMB_COM_TRANSACTION2中未传完的数据。
SMB_COM_FIND_CLOSE2 (0x34)
此命令在LAN Manager 1.2中引入。
此命令用来关闭由命令TRANS2_FIND_FIRST2而打开的搜索句柄,服务器释放所有和此句柄相关的资源。
SMB_COM_TREE_CONNECT (0x70)
已被废弃,客户端应该使用SMB_COM_TREE_CONNECT_ANDX来替代。
此命令用来建立一条客户端和服务器之间的连接,共享资源依靠共享名确定。连接建立后,此连接将用服务器返回的TID作为识别标记。
SMB_COM_TREE_DISCONNECT (0x71)
此命令用来关闭客户端访问服务器资源时使用的一条逻辑连接,连接依靠SMB头部的TID识别,断开后服务器将此TID视为无效的TID。所有和此TID相关的文件、目录及其他资源都被释放,文件和目录的锁也会被释放。
SMB_COM_NEGOTIATE (0x72)
此命令用来初始化服务器和客户端之间的SMB会话,必须在其他任何SMB命令发送之前完成。
每个SMB会话只能有一次协商过程,后续的SMB_COM_NEGOTIATE会被服务器拒绝并返回一个错误响应。
SMB_COM_SESSION_SETUP_ANDX (0x73)
此命令在LAN Manager 1.0中引入。相比最初的定义,请求和响应消息的格式都有所改变。本文介绍CIFS格式,在NT LAN Manager中定义。当协商使用NT LAN Manager时必须使用此格式。
此命令用来配置一个SMB会话。如果服务器运行在user级访问控制模式,至少发送一个SMB_COM_SESSION_SETUP_ANDX命令,执行用户登录服务器并建立一个有效的UID。
在CIFS协议中,在SMB_COM_SESSION_SETUP_ANDX命令执行成功之前发送SMB_COM_TREE_CONNECT或SMB_COM_TREE_CONNECT_ANDX是违反协议的,即使服务器运行在share级的访问控制模式。在SMB_COM_SESSION_SETUP_ANDX请求之后,包含SMB_COM_TREE_CONNECT_ANDX批处理请求的AndX链可以满足这一需求,匿名认证也可以满足这一需求(原句:Including an SMB_COM_TREE_CONNECT_ANDX batched
request in an AndX chain (section 2.2.3.4) following an SMB_COM_SESSION_SETUP_ANDX request is sufficient to fulfill this requirement. Anonymous authentication is also sufficient to fulfill this requirement)。
一个SMB会话用允许有多个SMB_COM_SESSION_SETUP_ANDX,用来建立额外的UID或建立额外的虚拟链路。
下面的命令可以放在SMB_COM_SESSION_SETUP_ANDX后面的AndX链中:
· SMB_COM_TREE_CONNECT_ANDX
· SMB_COM_OPEN
· SMB_COM_OPEN_ANDX
· SMB_COM_CREATE
· SMB_COM_CREATE_NEW
· SMB_COM_CREATE_DIRECTORY
· SMB_COM_DELETE
· SMB_COM_DELETE_DIRECTORY
· SMB_COM_FIND
· SMB_COM_FIND_UNIQUE
· SMB_COM_RENAME
· SMB_COM_NT_RENAME
· SMB_COM_CHECK_DIRECTORY
· SMB_COM_QUERY_INFORMATION
· SMB_COM_SET_INFORMATION
· SMB_COM_OPEN_PRINT_FILE
· SMB_COM_TRANSACTION
SMB_COM_LOGOFF_ANDX (0x74)
SMB头部UID标记的用户被注销,服务器将释放所有此UID相关的资源,包括释放锁,关闭所有的文件,断开连接,取消所有没有处理完的命令,标记此UID无效。
下面的命令可以放在SMB_COM_LOGOFF_ANDX后面的AndX链中:
· SMB_COM_SESSION_SETUP_ANDX.
SMB_COM_TREE_CONNECT_ANDX (0x75)
此命令在LAN Manager 1.0中引入。
此命令用来建立一条客户端和服务器之间的连接,共享资源依靠共享名确定。连接建立后,此连接将用服务器返回的TID作为识别标记。
下面的命令可以放在SMB_COM_TREE_CONNECT_ANDX后面的AndX链中:
· SMB_COM_OPEN
· SMB_COM_OPEN_ANDX
· SMB_COM_CREATE
· SMB_COM_CREATE_NEW
· SMB_COM_CREATE_DIRECTORY
· SMB_COM_DELETE
· SMB_COM_DELETE_DIRECTORY
· SMB_COM_SEARCH
· SMB_COM_FIND
· SMB_COM_FIND_UNIQUE
· SMB_COM_RENAME
· SMB_COM_NT_RENAME
· SMB_COM_CHECK_DIRECTORY
· SMB_COM_QUERY_INFORMATION
· SMB_COM_SET_INFORMATION
· SMB_COM_OPEN_PRINT_FILE
· SMB_COM_TRANSACTION
SMB_COM_QUERY_INFORMATION_DISK (0x80)
已被废弃。新的实现使用SMB_COM_TRANSACTION2和其子命令TRANS2_QUERY_FS_INFORMATION。
此命令可以由客户端发送,在SMB头部指明TID,获取相关目录的空间及剩余空间大小。客户端必须提供一个有效的TID,此TID应该由前面相关的SMB命令获取到的。
响应消息中返回的块或已申请单元大小,可能会与服务器实际物理或逻辑分配算法不一样,但是必须真实反映服务器上空间大小。
响应消息为每个域只返回16bit大小的信息,可能有些系统会请求大于此大小的信息。TotalUnits通常要远大于65535. 然而,典型的客户端一般只是请求磁盘大小和可用空间大小,因此服务器应该调整BlocksPerUnit和BlockSize的单位来适应16-bit的限制。如果经过调整还是超过了16-bit的限制,应该返回TotalUnits和FreeUnits所能表达的最大值。
SMB_COM_SEARCH (0x81)
已被废弃。新的实现使用TRANS2_FIND_FIRST2代替。
此命令用来在目录中搜索名字与指定通配符模板匹配的文件或其它对象。响应消息中在允许的最大传输字节内返回尽可能多的匹配的名字。响应消息中也包含一个key,用在后面的SMB_COM_SEARCH命令中返回下一组匹配的名字。
此命令只返回8.3格式的文件名称,和文件的基本属性,不支持Unicode,文件名只以扩展ASCII(OEM)字符返回。此命令后续没有关闭的操作。服务器要管理搜索的状态,直到搜索完成,或者PID或TID关闭,UID被置为无效(注销),或会话关闭。
SMB_COM_FIND (0x82)
已被废弃。新的实现使用SMB_COM_TRANSACTION2的子命令TRANS2_FIND_FIRST2来替代。
此命令的结构和目的都和SMB_COM_SEARCH相同,唯一不同的是有一个匹配的SMB_COM_FIND_CLOSE命令,允许用户主动关闭一个搜索操作。
SMB_COM_FIND_UNIQUE (0x83)
已被废弃。新的实现使用SMB_COM_TRANSACTION2的子命令TRANS2_FIND_FIRST2来替代。
SMB_COM_FIND_UNIQUE有着和SMB_COM_SEARCH及SMB_COM_FIND几乎一样的格式,不同的是请求消息中没有SMB_Date.ResumeKey。和SMB_COM_SEARCH及SMB_COM_FIND用法不同的是,它不要求服务器管理搜索上下文或其它状态。命令是单独使用的,没有后续命令。
和其它的搜索命令一样,请求可以包含至少一个的匹配名字。当响应返回后,搜索关闭。
SMB_COM_FIND_CLOSE (0x84)
已被废弃。新的实现使用SMB_COM_TRANSACTION2的子命令TRANS2_FIND_FIRST2替代。
此命令关闭由SMB_COM_FIND打开的目录搜索。初始化SMB_COM_FIND请求逻辑上打开并启动了搜索。后续的SMB_COM_FIND使用合法的ResumeKey可以继续搜索。SMB_COM_FIND_CLOSE关闭了搜索,服务器释放管理搜索上下文用到的所有资源。
如果SMB_COM_FIND失败(返回错误),搜索不会打开,这个命令也不用调用来关闭搜索。此命令不应该用来关闭SMB_COM_SEARCH开启的搜索。
此命令的格式和SMB_COM_SEARCH及SMB_COM_FIND几乎相同,只是响应消息中没有字段SMB_Data.DirectoryInformationData。
SMB_COM_NT_TRANSACT (0xA0)
此命令在NT LAN Manager中引入。
此命令扩展了由SMB_COM_TRANSACTION2提供的文件系统访问服务,允许处理非常大的参数和数据块。
SMB_COM_NT_TRANSACT消息可以超过单个SMB消息允许的最大值(由参数MaxBufferSize决定)。在这种情况下,客户端使用一个或多个SMB_COM_NT_TRANSACT_SECONDARY消息来传输和消息初始化不匹配的data和Parameter。
如果客户端没有发送完所有的SMB_Data.Trans_Data,会将DataCount设置为小于TotalDataCount的一个值。同样的,如果SMB_Data.Trans_Parameters没有发送完,会设置ParameterCount为一个小于TotalParameterCount的值。参数部分优先级高于数据部分,客户端在每个消息中应该尽量多的发送数据。服务器应该可以接收无序到达的SMB_Data.Trans_Parameters 和 SMB_Data.Trans_Data,不论是大量还是少量的数据。
在请求和响应消息中,SMB_Data.NT_Trans_Parameters和SMB_Data.nt_Trans_Data的位置和长度都是由SMB_Parameters.ParameterOffset、SMB_Parameters.ParameterCount, SMB_Parameters.DataOffset和SMB_Parameters.DataCount决定。另外需要说明的是,SMB_Parameters.ParameterDisplacement和SMB_Parameters.DataDisplacement可以用来改变发送数据段的序号。服务器应该按照自己顺序发送,优先发送SMB_Data.NT_Trans_Parameters。客户端应该准备好组装收到的SMB_Data.NT_Trans_Parameters和SMB_Data.NT_Trans_Data,即使它们是乱序到达的。
SMB_COM_NT_TRANSACT_SECONDARY (0xA1)
此命令用来完成SMB_COM_NT_TRANSACT中未传完的数据。
SMB_COM_NT_CREATE_ANDX (0xA2)
此命令在NT LAN Manager中引入。
此命令用来创建并打开一个新文件,或者打开一个已存在的文件,或打开并清空一个已存在的文件,或创建一个目录,或创建一个命名管道。返回的FID可以用在后续的请求消息中。
消息中包含客户端想要创建或打开的文件名,目录,或命名管道和RootDirectoryFID。如果执行成功,服务器返回一个FID标记打开的资源。客户端在后续的请求消息中必须携带此FID。客户端必须拥有对资源所在目录的写权限,才能创建一个新的文件或目录;或者拥有文件的写权限来执行截断文件的操作。
下面的命令可以放在SMB_COM_NT_CREATE_ANDX后面的AndX链中:
· SMB_COM_READ
· SMB_COM_READ_ANDX
· SMB_COM_IOCTL
SMB_COM_NT_CANCEL (0xA4)
此命令在NT LAN Manager中引入。
此命令使客户端可以取消掉pending态的请求。服务器用SMB_Header中的信息识别客户端想要取消哪些请求,服务器可以取消或立即处理这些请求。服务器对此消息不能回复响应消息。客户端应该依靠服务器对指定取消的消息的响应来判断取消消息的结果。如果服务器不能识别客户端请求中的指定消息,也不应该发送响应。
此命令主要用来取消由SMB_COM_NT_TRANSACT和NT_TRANSACT_NOTIFY_CHANGE子命令引起的多余的通知消息。客户端一般用NT_TRANSACT_NOTIFY_CHANGE命令避免轮询目录的改变。此命令另外的用途包括取消一个无限期等待繁忙资源的请求,或尝试很多次来等待一个资源的请求。
SMB_COM_OPEN_PRINT_FILE (0xC0)
此命令用来创建一个打印队列缓冲文件。此文件将会在打印机中排队。当文件打印完毕后,服务器应该删除这个文件。
SMB_COM_INVALID (0xFE)
此命令在LAN Manager 1.0中引入。这是一个保留的值,指明一个非法的命令。
客户端不应该发送此命令,服务器收到此命令后应该返回STATUS_SMB_BAD_COMMAND (ERRDOC/ERRbadfunc)。
SMB_COM_NO_ANDX_COMMAND (0xFF)
此命令在LAN Manager 1.0中引入。设计此命令的目的是用来指明一个AndX链的结束。
客户端不应该在主命令中使用此命令,服务器在主命令中收到此命令后应该返回STATUS_SMB_BAD_COMMAND (ERRSRV/ERRbadcmd)。
在早期的SMB协议规格(见[IBM-SMB])中,此命令保留来做特定协议的扩展。这个用法已过时。在最新的微软协议文档中,包括[SMB-CORE]和[MSFT-XEXTNP],都没有描述此命令作为协议扩展或其它目的的作用。
现实cifs数据包
上图command域是Tree Connect Andx(0x75),用来建立一条客户端和服务器之间的连接。
可以看到UID已经存在,说明认证已经通过了,PID为46900,标示客户端应用程序的pid
word count为4,表示后面8个字节为参数域
Byte Count为49,标示后面49字节为buffer内容