smbclient提供了类似FTP式的共享文件操作功能, 本篇从源码角度讲解smbclient的实现,smbclient命令的具体使用可通过help命令和互联网查到大量资料。

以下从源码角度分析一个smbclient命令是如何发到远端机器上和处理返回结果的。这里以一个简单的命令“close <fnum>”为例,分析程序的整个过程如下:

step 1. cmd_close(void)位于source3/client/client.c中。每个smbclient命令都有一个类似cmd_***命名的函数,这些函数作用是为step 2中的cli_***函数准备参数。

- 从全局内存stackframe获取临时内存“停靠点”。该步主要使用talloc库并配合samba自身的需要完成内存的管理。具体可参见上一篇博文的talloc加深理解。

- 分析传入的<fnum>, 简单调用atoi转换为字符串类型。

- 调用cli_close()。

Step 2. cli_close(cli, fnum)位于source3/client/client.c中。 它接收cmd_***传递的函数,做实质性的工作。这里第一个参数cli是cli_state全局类型数据,该数据结构中几乎包含了当前连接的connection的绝大多数信息,例如:

cli_state的前驱和后继、当前connection 信息、客户domain名、用户名、server domain、os、posix 能力、打开的管道list、机会锁信息、使用smb1 or smb2?及其相关联的session、tree connection、打开的句柄。第二

个参数是上面准备的打开的句柄。不同的cli_***command可能需要另外的参数,这些参数主要是为下层协议具体command准备的。可参见CIFS or SMB2协议来确定每个命令具体需要的参数有哪些。

- 根据cli->connection->protocol类型判断当前connection所使用的协议类型,若为SMB2,则调用SMB2处理函数cli_smb2_close_fnum(位于source3/libsmb/cli_smb2_fnum.c中)。这里重点分析SMB1处理。

- 若当前connection使用smb1,则根据当前connection->的event等待队列来判断是否有outgoing或pending的message,如果有则出错返回。(因为这里我们使用的都是同步的smb1 message)

- 调用samba_tevent_context_init分配tevent

- 调用cli_close_send()发送close immediate CIFS message。后续具体分析这个函数。

- 调用tevent_req_poll()等待event接收事件

- 调用cli_close_recv()接收server返回的close 数据报并返回

上面蓝色标记部分为IO处理的tevent库使用,会另文介绍。本文继续深入分析红色部分的协议处理部分,两个红色标记函数完成了协议组包、协议发送和协议接收处理。

cli_close_send():

Step 1: 调用cli_close_create(),根据协议组包并设置event类型和callback函数

- 调用tevent_req_create()创建一个immediate类型event,并设置状态为TEVENT_REQ_IN_PROGRESS状态;

- 调用cli_smb_req_create(TALLOC_CTX, tevent_context, cli_state, smb_command, additinal_flags, wct, *vwv, iov_count, iovec*),然后又向下调用smb1cli_req_create()(位于libcli/smb/smbXcli_base.c中)完成

按协议的具体组包工作。组包时需要注意,SMB1在组包时并没有定义每个CIFS协议的完整数据包格式,只是定义了header(加上wct)字段,发送是通过控制iov和iov_count来进行的,具体看下面code:

    smb1cli_req_flags(conn->protocol,conn->smb1.capabilities,smb_command,additional_flags,clear_flags,&flags,additional_flags2,clear_flags2,&flags2);  //获取当前命令所需的flags//设置CIFS header的各个域,完成大小端转换SIVAL(state->smb1.hdr, 0,           SMB_MAGIC); SCVAL(state->smb1.hdr, HDR_COM,     smb_command);SIVAL(state->smb1.hdr, HDR_RCLS,    NT_STATUS_V(NT_STATUS_OK));SCVAL(state->smb1.hdr, HDR_FLG,     flags);SSVAL(state->smb1.hdr, HDR_FLG2,    flags2);SSVAL(state->smb1.hdr, HDR_PIDHIGH, pid >> 16);SSVAL(state->smb1.hdr, HDR_TID,     tid);SSVAL(state->smb1.hdr, HDR_PID,     pid);SSVAL(state->smb1.hdr, HDR_UID,     uid);SSVAL(state->smb1.hdr, HDR_MID,     0); /* this comes later */SCVAL(state->smb1.hdr, HDR_WCT,     wct);state->smb1.vwv = vwv;// ???//计算bcc字段SSVAL(state->smb1.bytecount_buf, 0, smbXcli_iov_len(bytes_iov, iov_count));//以下为每个SMB1 command都包含的域state->smb1.iov[0].iov_base = (void *)state->length_hdr; //“SMB”state->smb1.iov[0].iov_len  = sizeof(state->length_hdr);state->smb1.iov[1].iov_base = (void *)state->smb1.hdr; //header域state->smb1.iov[1].iov_len  = sizeof(state->smb1.hdr);state->smb1.iov[2].iov_base = (void *)state->smb1.vwv; //wct字段具体包含的数据state->smb1.iov[2].iov_len  = wct * sizeof(uint16_t);state->smb1.iov[3].iov_base = (void *)state->smb1.bytecount_buf;//bcc域state->smb1.iov[3].iov_len  = sizeof(uint16_t);//特殊smb1 command若还有其他字段则通过iov[4]进行发送if (iov_count != 0) {memcpy(&state->smb1.iov[4], bytes_iov,iov_count * sizeof(*bytes_iov));}state->smb1.iov_count = iov_count + 4;

- 组包结束后调用tevent_req_set_callbak()设置该event的callback函数为cli_close_done(),在该函数中调用cli_smb_recv()函数完成smb数据包的接收。注意,此时组包和event相关注册活动均已完成,ready for 发送。

Step 2: 调用smb1cli_req_chain_submit(),该函数完成具体的message发送工作。

cli_close_recv():

- 由于注册的是immediate时间,程序将block在上一步的tevent_req_poll()直到对应event接到通知,并从注册的callback中返回。此时我们已经接收收到了close的返回数据报(callback函数接收处理的),针对close command只需要简单处理返回值即可。其他复杂command可能需要对返回值作进一步的分析,如保存打开的文件句柄、保存treeid等信息。

总结:

其实client端的实现还是相对比较简单,关键点是tevent库的使用和协议的组包分析。tevent库的使用可以通过资料快速掌握,但协议的组包和处理包括大量细节,没必要全部掌握,分析一个简单命令即可。

转载于:https://www.cnblogs.com/stephen-init/p/4005611.html

Samba 源码解析之SMBclient命令流相关推荐

  1. FileZilla Server源码解析之LIST命令

    FileZilla Server源码解析之LIST命令 如需转载请标明出处:http://blog.csdn.net/itas109 QQ技术交流群:129518033 FileZilla版本:Fil ...

  2. Sentinel滑动时间窗限流算法原理及源码解析(上)

    文章目录 时间窗限流算法 滑动时间窗口 滑动时间窗口算法改进 滑动时间窗口源码解析 时间窗限流算法 10t到16t 10个请求 16t-20t 50个请求 20t-26t 60个请求 26t到30t ...

  3. Redis源码解析(15) 哨兵机制[2] 信息同步与TILT模式

    Redis源码解析(1) 动态字符串与链表 Redis源码解析(2) 字典与迭代器 Redis源码解析(3) 跳跃表 Redis源码解析(4) 整数集合 Redis源码解析(5) 压缩列表 Redis ...

  4. Redis源码-String:Redis String命令、Redis String存储原理、Redis String三种编码类型、Redis字符串SDS源码解析、Redis String应用场景

    Redis源码-String:Redis String命令.Redis String存储原理.Redis String三种编码类型.Redis字符串SDS源码解析.Redis String应用场景 R ...

  5. Guava RateLimiter限流源码解析和实例应用

    2019独角兽企业重金招聘Python工程师标准>>> 在开发高并发系统时有三把利器用来保护系统:缓存.降级和限流 缓存 缓存的目的是提升系统访问速度和增大系统处理容量 降级 降级是 ...

  6. JDK源码解析 Runable是一个典型命令模式,Runnable担当命令的角色,Thread充当的是调用者,start方法就是其执行方法

    JDK源码解析 Runnable是一个典型命令模式, Runnable担当命令的角色,Thread充当的是调用者,start方法就是其执行方法 /命令接口(抽象命令角色) public interfa ...

  7. JDK源码解析 —— IO流中的包装类使用到了装饰者模式

    JDK源码解析 IO流中的包装类使用到了装饰者模式. BufferedInputStream, BufferedOutputStream, BufferedReader, BufferedWriter ...

  8. 熔断器 Hystrix 源码解析 —— 命令执行(三)之执行超时

    2019独角兽企业重金招聘Python工程师标准>>> 摘要: 原创出处 http://www.iocoder.cn/Hystrix/command-execute-third-ti ...

  9. 【OS xv6】1 万字详解shell源码解析命令(内含wsl+vscode调试xv6教程 文档第一章助读)

    现在前面的 嘻嘻几百年没写文了确实没时间,等搞完毕设可以一起重温重温.最近学os,读源码发现还挺多东西得整理的,尤其途中有必要找资料整理的时候,内容有点多有点乱,写在源码已经显得不现实了.用的vsco ...

最新文章

  1. iOS10 UI设计基础教程
  2. Qt Creator使用Memcheck检测内存泄漏
  3. luogu P1880 [NOI1995]石子合并
  4. MongoDB(五)-- 副本集(replica Set)
  5. eclipse springmvc+Thymeleaf
  6. Tensorflow——Variable变量(打印数字小实例)
  7. 那个抗血栓机器人_美国DJO抗血栓压力袜
  8. Android、IOS文字居中偏离的解决方案
  9. oracle 12.1.0.2中对象锁对系统的较大影响
  10. DFS CCPC2017 南宁I题
  11. Docker教程小白实操入门(3)--如何启动一个已经停止的容器
  12. HUSTOJ平台的搭建
  13. Unity网络编程一: 基于Socket搭建一个服务器
  14. linux硬盘序列号在哪看,linux下怎样查看硬盘型号和硬盘序列号
  15. 2022-03-09:我们正在玩一个猜数游戏,游戏规则如下: 我从 1 到 n 之间选择一个数字。 你来猜我选了哪个数字。 如果你猜到正确的数字,就会 赢得游戏 。 如果你猜错了,那么我会告诉你,我选
  16. OpenCV-识别细胞图中的细胞总数
  17. win7所有服务被禁用(应该是大多数被禁用)
  18. 西门吹雪和他的剑——剑神和剑道
  19. 程序员励志视频_5个最适合程序员的励志视频
  20. 红绿蓝三色阈值,比赛

热门文章

  1. 最好懂的python文件读写(详解)
  2. 恩易物联智慧电梯解决方案(物业单位)
  3. vue条件样式 设置背景为图片自适应大小
  4. 快解析动态域名解析,实现外网访问内网数据库
  5. 色彩心理学对网页设计有多大影响力?
  6. 【统计学】【2009.03】【含源码】时间序列分析和统计过程控制工具在财务数据中的应用
  7. 教你一步步如何用Gradle来搭建Vert.x 4 应用
  8. android控件显示顺序控制
  9. C语言学习:剪切板UNICODE码使用
  10. mysql update批量更新_MySql中4种批量更新的方法