samba 客户 建立会话

/****************************************************************************
 Send a session setup. The username and workgroup is in UNIX character
 format and must be converted to DOS codepage format before sending. If the
 password is in plaintext, the same should be done.
****************************************************************************/
//cli clie_state对象,pass明文密码,ntpass加密密码
NTSTATUS cli_session_setup(struct cli_state *cli,
			   const char *user,
			   const char *pass, int passlen,
			   const char *ntpass, int ntpasslen,
			   const char *workgroup)
{
	char *p;
	char *user2;

	if (user) {
		user2 = talloc_strdup(talloc_tos(), user);//复制user到user2(根据samba talloc库,user2是talloc_tos()子节点)
	} else {
		user2 = talloc_strdup(talloc_tos(), "");
	}
	if (user2 == NULL) {//内存不足
		return NT_STATUS_NO_MEMORY;
	}

	if (!workgroup) {//如果指针空
		workgroup = "";//指针指向字符串""
	}

	/* allow for workgroups as part of the username */
	if ((p=strchr_m(user2,'\\')) || (p=strchr_m(user2,'/')) ||
	    (p=strchr_m(user2,*lp_winbind_separator()))) { //查找user2中是否有\,/或者指定的分隔符
		*p = 0;//user2的分隔符用'\0'代替,也就是舍弃分隔符后的部分
		user = p+1;//user指向等于分隔符后面的部分
		strupper_m(user2);//分隔符前面部分大写
		workgroup = user2;//workgroup指向大写形式的分隔符前面部分
	}

	if (cli->protocol < PROTOCOL_LANMAN1) {//smb协议小于LANMAN1版本core,coreplus,不接受用户名
		/*
		 * Ensure cli->server_domain,
		 * cli->server_os and cli->server_type
		 * are valid pointers.
		 */
		cli->server_domain = talloc_strdup(cli, "");
		cli->server_os = talloc_strdup(cli, "");
		cli->server_type = talloc_strdup(cli, "");
		if (cli->server_domain == NULL ||
				cli->server_os == NULL ||
				cli->server_type == NULL) {
			return NT_STATUS_NO_MEMORY;
		}
		return NT_STATUS_OK;\\成功 0x0000
	}

	/* now work out what sort of session setup we are going to
           do. I have split this into separate functions to make the
           flow a bit easier to understand (tridge) session的类型,高协议版本兼容低协议版本*/

	/* if its an older server then we have to use the older request format */

	if (cli->protocol < PROTOCOL_NT1) {\\LANMAN1, LANMAN2
		if (!lp_client_lanman_auth() && passlen != 24 && (*pass)) {
			DEBUG(1, ("Server requested LM password but 'client lanman auth = no'"
				  " or 'client ntlmv2 auth = yes'\n"));
			return NT_STATUS_ACCESS_DENIED;//拒绝连接
		}

		if ((cli->sec_mode & NEGOTIATE_SECURITY_CHALLENGE_RESPONSE) == 0 && //挑战响应模式,在NTLMv1和NTLMv2上使用
		    !lp_client_plaintext_auth() && (*pass)) {//非挑战响应模式,非明文,但是明文密码存在
			DEBUG(1, ("Server requested LM password but 'client plaintext auth = no'"
				  " or 'client ntlmv2 auth = yes'\n"));
			return NT_STATUS_ACCESS_DENIED;
		}

		return cli_session_setup_lanman2(cli, user, pass, passlen,
						 workgroup);
	}

	/* if no user is supplied then we have to do an anonymous connection.
	   passwords are ignored */

	if (!user || !*user)//没有用户的时候,用guest账户
		return cli_session_setup_guest(cli);

	/* if the server is share level then send a plaintext null
           password at this point. The password is sent in the tree
           connect */

	if ((cli->sec_mode & NEGOTIATE_SECURITY_USER_LEVEL) == 0) //不需要用户验证
		return cli_session_setup_plain(cli, user, "", workgroup);

	/* if the server doesn't support encryption then we have to use 
	   plaintext. The second password is ignored */

	if ((cli->sec_mode & NEGOTIATE_SECURITY_CHALLENGE_RESPONSE) == 0) {
		if (!lp_client_plaintext_auth() && (*pass)) {
			DEBUG(1, ("Server requested LM password but 'client plaintext auth = no'"
				  " or 'client ntlmv2 auth = yes'\n"));
			return NT_STATUS_ACCESS_DENIED;
		}
		return cli_session_setup_plain(cli, user, pass, workgroup);
	}

	/* if the server supports extended security then use SPNEGO */

	if (cli->capabilities & CAP_EXTENDED_SECURITY) {
		ADS_STATUS status = cli_session_setup_spnego(cli, user, pass,
							     workgroup, NULL);
		if (!ADS_ERR_OK(status)) {
			DEBUG(3, ("SPNEGO login failed: %s\n", ads_errstr(status)));
			return ads_ntstatus(status);
		}
	} else {
		NTSTATUS status;

		/* otherwise do a NT1 style session setup */
		status = cli_session_setup_nt1(cli, user, pass, passlen,
					       ntpass, ntpasslen, workgroup);
		if (!NT_STATUS_IS_OK(status)) {
			DEBUG(3,("cli_session_setup: NT1 session setup "
				 "failed: %s\n", nt_errstr(status)));
			return status;
		}
	}

	if (strstr(cli->server_type, "Samba")) {
		cli->is_samba = True;
	}

	return NT_STATUS_OK;
}

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值