⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 srv_pipe.c

📁 samba-3.0.22.tar.gz 编译smb服务器的源码
💻 C
📖 第 1 页 / 共 5 页
字号:
	p->out_data.data_sent_length = 0;	p->out_data.current_pdu_len = prs_offset(&outgoing_pdu);	p->out_data.current_pdu_sent = 0;	prs_mem_free(&outgoing_pdu);	return True;}#endif/******************************************************************* Ensure a bind request has the correct abstract & transfer interface. Used to reject unknown binds from Win2k.*******************************************************************/BOOL check_bind_req(struct pipes_struct *p, RPC_IFACE* abstract,                    RPC_IFACE* transfer, uint32 context_id){	char *pipe_name = p->name;	int i=0;	fstring pname;		fstrcpy(pname,"\\PIPE\\");	fstrcat(pname,pipe_name);	DEBUG(3,("check_bind_req for %s\n", pname));	/* we have to check all now since win2k introduced a new UUID on the lsaprpc pipe */			for ( i=0; pipe_names[i].client_pipe; i++ ) {		DEBUG(10,("checking %s\n", pipe_names[i].client_pipe));		if ( strequal(pipe_names[i].client_pipe, pname)			&& (abstract->version == pipe_names[i].abstr_syntax.version) 			&& (memcmp(&abstract->uuid, &pipe_names[i].abstr_syntax.uuid, sizeof(struct uuid)) == 0)			&& (transfer->version == pipe_names[i].trans_syntax.version)			&& (memcmp(&transfer->uuid, &pipe_names[i].trans_syntax.uuid, sizeof(struct uuid)) == 0) ) {			struct api_struct 	*fns = NULL;			int 			n_fns = 0;			PIPE_RPC_FNS		*context_fns;						if ( !(context_fns = SMB_MALLOC_P(PIPE_RPC_FNS)) ) {				DEBUG(0,("check_bind_req: malloc() failed!\n"));				return False;			}						/* save the RPC function table associated with this bind */						get_pipe_fns(i, &fns, &n_fns);						context_fns->cmds = fns;			context_fns->n_cmds = n_fns;			context_fns->context_id = context_id;						/* add to the list of open contexts */						DLIST_ADD( p->contexts, context_fns );						break;		}	}	if(pipe_names[i].client_pipe == NULL) {		return False;	}	return True;}/******************************************************************* Register commands to an RPC pipe*******************************************************************/NTSTATUS rpc_pipe_register_commands(int version, const char *clnt, const char *srv, const struct api_struct *cmds, int size){        struct rpc_table *rpc_entry;	if (!clnt || !srv || !cmds) {		return NT_STATUS_INVALID_PARAMETER;	}	if (version != SMB_RPC_INTERFACE_VERSION) {		DEBUG(0,("Can't register rpc commands!\n"			 "You tried to register a rpc module with SMB_RPC_INTERFACE_VERSION %d"			 ", while this version of samba uses version %d!\n", 			 version,SMB_RPC_INTERFACE_VERSION));		return NT_STATUS_OBJECT_TYPE_MISMATCH;	}	/* TODO: 	 *	 * we still need to make sure that don't register the same commands twice!!!	 * 	 * --metze	 */        /* We use a temporary variable because this call can fail and            rpc_lookup will still be valid afterwards.  It could then succeed if           called again later */	rpc_lookup_size++;        rpc_entry = SMB_REALLOC_ARRAY(rpc_lookup, struct rpc_table, rpc_lookup_size);        if (NULL == rpc_entry) {                rpc_lookup_size--;                DEBUG(0, ("rpc_pipe_register_commands: memory allocation failed\n"));                return NT_STATUS_NO_MEMORY;        } else {                rpc_lookup = rpc_entry;        }                rpc_entry = rpc_lookup + (rpc_lookup_size - 1);        ZERO_STRUCTP(rpc_entry);        rpc_entry->pipe.clnt = SMB_STRDUP(clnt);        rpc_entry->pipe.srv = SMB_STRDUP(srv);        rpc_entry->cmds = SMB_REALLOC_ARRAY(rpc_entry->cmds, struct api_struct, rpc_entry->n_cmds + size);        memcpy(rpc_entry->cmds + rpc_entry->n_cmds, cmds, size * sizeof(struct api_struct));        rpc_entry->n_cmds += size;                return NT_STATUS_OK;}/******************************************************************* Handle a SPNEGO krb5 bind auth.*******************************************************************/static BOOL pipe_spnego_auth_bind_kerberos(pipes_struct *p, prs_struct *rpc_in_p, RPC_HDR_AUTH *pauth_info,		DATA_BLOB *psecblob, prs_struct *pout_auth){	return False;}/******************************************************************* Handle the first part of a SPNEGO bind auth.*******************************************************************/static BOOL pipe_spnego_auth_bind_negotiate(pipes_struct *p, prs_struct *rpc_in_p,					RPC_HDR_AUTH *pauth_info, prs_struct *pout_auth){	DATA_BLOB blob;	DATA_BLOB secblob;	DATA_BLOB response;	DATA_BLOB chal;	char *OIDs[ASN1_MAX_OIDS];        int i;	NTSTATUS status;        BOOL got_kerberos_mechanism = False;	AUTH_NTLMSSP_STATE *a = NULL;	RPC_HDR_AUTH auth_info;	ZERO_STRUCT(secblob);	ZERO_STRUCT(chal);	ZERO_STRUCT(response);	/* Grab the SPNEGO blob. */	blob = data_blob(NULL,p->hdr.auth_len);	if (!prs_copy_data_out((char *)blob.data, rpc_in_p, p->hdr.auth_len)) {		DEBUG(0,("pipe_spnego_auth_bind_negotiate: Failed to pull %u bytes - the SPNEGO auth header.\n",			(unsigned int)p->hdr.auth_len ));		goto err;	}	if (blob.data[0] != ASN1_APPLICATION(0)) {		goto err;	}	/* parse out the OIDs and the first sec blob */	if (!parse_negTokenTarg(blob, OIDs, &secblob)) {		DEBUG(0,("pipe_spnego_auth_bind_negotiate: Failed to parse the security blob.\n"));		goto err;        }	if (strcmp(OID_KERBEROS5, OIDs[0]) == 0 || strcmp(OID_KERBEROS5_OLD, OIDs[0]) == 0) {		got_kerberos_mechanism = True;	}	for (i=0;OIDs[i];i++) {		DEBUG(3,("pipe_spnego_auth_bind_negotiate: Got OID %s\n", OIDs[i]));		SAFE_FREE(OIDs[i]);	}	DEBUG(3,("pipe_spnego_auth_bind_negotiate: Got secblob of size %lu\n", (unsigned long)secblob.length));	if ( got_kerberos_mechanism && ((lp_security()==SEC_ADS) || lp_use_kerberos_keytab()) ) {		BOOL ret = pipe_spnego_auth_bind_kerberos(p, rpc_in_p, pauth_info, &secblob, pout_auth);		data_blob_free(&secblob);		data_blob_free(&blob);		return ret;	}	if (p->auth.auth_type == PIPE_AUTH_TYPE_SPNEGO_NTLMSSP && p->auth.a_u.auth_ntlmssp_state) {		/* Free any previous auth type. */		free_pipe_ntlmssp_auth_data(&p->auth);	}	/* Initialize the NTLM engine. */	status = auth_ntlmssp_start(&a);	if (!NT_STATUS_IS_OK(status)) {		goto err;	}	/*	 * Pass the first security blob of data to it.	 * This can return an error or NT_STATUS_MORE_PROCESSING_REQUIRED	 * which means we need another packet to complete the bind.	 */        status = auth_ntlmssp_update(a, secblob, &chal);	if (!NT_STATUS_EQUAL(status, NT_STATUS_MORE_PROCESSING_REQUIRED)) {		DEBUG(3,("pipe_spnego_auth_bind_negotiate: auth_ntlmssp_update failed.\n"));		goto err;	}	/* Generate the response blob we need for step 2 of the bind. */	response = spnego_gen_auth_response(&chal, status, OID_NTLMSSP);	/* Copy the blob into the pout_auth parse struct */	init_rpc_hdr_auth(&auth_info, RPC_SPNEGO_AUTH_TYPE, pauth_info->auth_level, RPC_HDR_AUTH_LEN, 1);	if(!smb_io_rpc_hdr_auth("", &auth_info, pout_auth, 0)) {		DEBUG(0,("pipe_spnego_auth_bind_negotiate: marshalling of RPC_HDR_AUTH failed.\n"));		goto err;	}	if (!prs_copy_data_in(pout_auth, (char *)response.data, response.length)) {		DEBUG(0,("pipe_spnego_auth_bind_negotiate: marshalling of data blob failed.\n"));		goto err;	}	p->auth.a_u.auth_ntlmssp_state = a;	p->auth.auth_data_free_func = &free_pipe_ntlmssp_auth_data;	p->auth.auth_type = PIPE_AUTH_TYPE_SPNEGO_NTLMSSP;	data_blob_free(&blob);	data_blob_free(&secblob);	data_blob_free(&chal);	data_blob_free(&response);	/* We can't set pipe_bound True yet - we need an RPC_ALTER_CONTEXT response packet... */	return True; err:	data_blob_free(&blob);	data_blob_free(&secblob);	data_blob_free(&chal);	data_blob_free(&response);	p->auth.a_u.auth_ntlmssp_state = NULL;	return False;}/******************************************************************* Handle the second part of a SPNEGO bind auth.*******************************************************************/static BOOL pipe_spnego_auth_bind_continue(pipes_struct *p, prs_struct *rpc_in_p,					RPC_HDR_AUTH *pauth_info, prs_struct *pout_auth){	RPC_HDR_AUTH auth_info;	DATA_BLOB spnego_blob;	DATA_BLOB auth_blob;	DATA_BLOB auth_reply;	DATA_BLOB response;	AUTH_NTLMSSP_STATE *a = p->auth.a_u.auth_ntlmssp_state;	ZERO_STRUCT(spnego_blob);	ZERO_STRUCT(auth_blob);	ZERO_STRUCT(auth_reply);	ZERO_STRUCT(response);	if (p->auth.auth_type != PIPE_AUTH_TYPE_SPNEGO_NTLMSSP || !a) {		DEBUG(0,("pipe_spnego_auth_bind_continue: not in NTLMSSP auth state.\n"));		goto err;	}	/* Grab the SPNEGO blob. */	spnego_blob = data_blob(NULL,p->hdr.auth_len);	if (!prs_copy_data_out((char *)spnego_blob.data, rpc_in_p, p->hdr.auth_len)) {		DEBUG(0,("pipe_spnego_auth_bind_continue: Failed to pull %u bytes - the SPNEGO auth header.\n",			(unsigned int)p->hdr.auth_len ));		goto err;	}	if (spnego_blob.data[0] != ASN1_CONTEXT(1)) {		DEBUG(0,("pipe_spnego_auth_bind_continue: invalid SPNEGO blob type.\n"));		goto err;	}	if (!spnego_parse_auth(spnego_blob, &auth_blob)) {		DEBUG(0,("pipe_spnego_auth_bind_continue: invalid SPNEGO blob.\n"));		goto err;	}	/*	 * The following call actually checks the challenge/response data.	 * for correctness against the given DOMAIN\user name.	 */		if (!pipe_ntlmssp_verify_final(p, &auth_blob)) {		goto err;	}	data_blob_free(&spnego_blob);	data_blob_free(&auth_blob);	/* Generate the spnego "accept completed" blob - no incoming data. */	response = spnego_gen_auth_response(&auth_reply, NT_STATUS_OK, OID_NTLMSSP);	/* Copy the blob into the pout_auth parse struct */	init_rpc_hdr_auth(&auth_info, RPC_SPNEGO_AUTH_TYPE, pauth_info->auth_level, RPC_HDR_AUTH_LEN, 1);	if(!smb_io_rpc_hdr_auth("", &auth_info, pout_auth, 0)) {		DEBUG(0,("pipe_spnego_auth_bind_continue: marshalling of RPC_HDR_AUTH failed.\n"));		goto err;	}	if (!prs_copy_data_in(pout_auth, (char *)response.data, response.length)) {		DEBUG(0,("pipe_spnego_auth_bind_continue: marshalling of data blob failed.\n"));		goto err;	}	data_blob_free(&auth_reply);	data_blob_free(&response);	p->pipe_bound = True;	return True; err:	data_blob_free(&spnego_blob);	data_blob_free(&auth_blob);	data_blob_free(&auth_reply);	data_blob_free(&response);	free_pipe_ntlmssp_auth_data(&p->auth);	p->auth.a_u.auth_ntlmssp_state = NULL;	return False;}/******************************************************************* Handle an schannel bind auth.*******************************************************************/static BOOL pipe_schannel_auth_bind(pipes_struct *p, prs_struct *rpc_in_p,					RPC_HDR_AUTH *pauth_info, prs_struct *pout_auth){	RPC_HDR_AUTH auth_info;	RPC_AUTH_SCHANNEL_NEG neg;	RPC_AUTH_VERIFIER auth_verifier;	BOOL ret;	struct dcinfo stored_dcinfo;	uint32 flags;	if (!smb_io_rpc_auth_schannel_neg("", &neg, rpc_in_p, 0)) {		DEBUG(0,("pipe_schannel_auth_bind: Could not unmarshal SCHANNEL auth neg\n"));		return False;	}	ZERO_STRUCT(stored_dcinfo);	become_root();	ret = secrets_restore_schannel_session_info(p->mem_ctx, neg.myname, &stored_dcinfo);	unbecome_root();	if (!ret) {		DEBUG(0, ("pipe_schannel_auth_bind: Attempt to bind using schannel without successful serverauth2\n"));		return False;	}	p->auth.a_u.schannel_auth = TALLOC_P(p->pipe_state_mem_ctx, struct schannel_auth_struct);	if (!p->auth.a_u.schannel_auth) {		return False;	}	memset(p->auth.a_u.schannel_auth->sess_key, 0, sizeof(p->auth.a_u.schannel_auth->sess_key));	memcpy(p->auth.a_u.schannel_auth->sess_key, stored_dcinfo.sess_key, sizeof(stored_dcinfo.sess_key));	p->auth.a_u.schannel_auth->seq_num = 0;	/*	 * JRA. Should we also copy the schannel session key into the pipe session key p->session_key	 * here ? We do that for NTLMSPP, but the session key is already set up from the vuser	 * struct of the person who opened the pipe. I need to test this further. JRA.	 */	/* The client opens a second RPC NETLOGON pipe without		doing a auth2. The credentials for the schannel are		re-used from the auth2 the client did before. */	p->dc = TALLOC_ZERO_P(p->pipe_state_mem_ctx, struct dcinfo);	if (!p->dc) {		return False;	}	*p->dc = stored_dcinfo;	init_rpc_hdr_auth(&auth_info, RPC_SCHANNEL_AUTH_TYPE, pauth_info->auth_level, RPC_HDR_AUTH_LEN, 1);	if(!smb_io_rpc_hdr_auth("", &auth_info, pout_auth, 0)) {		DEBUG(0,("pipe_schannel_auth_bind: marshalling of RPC_HDR_AUTH failed.\n"));		return False;	}	/*** SCHANNEL verifier ***/	init_rpc_auth_verifier(&auth_verifier, "\001", 0x0);	if(!smb_io_rpc_schannel_verifier("", &auth_verifier, pout_auth, 0)) {		DEBUG(0,("pipe_schannel_auth_bind: marshalling of RPC_AUTH_VERIFIER failed.\n"));		return False;	}	prs_align(pout_auth);	flags = 5;	if(!prs_uint32("flags ", pout_auth, 0, &flags)) {		return False;	}	DEBUG(10,("pipe_schannel_auth_bind: schannel auth: domain [%s] myname [%s]\n",		neg.domain, neg.myname));	/* We're finished with this bind - no more packets. */	p->auth.auth_data_free_func = NULL;	p->auth.auth_type = PIPE_AUTH_TYPE_SCHANNEL;	p->pipe_bound = True;	return True;}/******************************************************************* Handle an NTLMSSP bind auth.*******************************************************************/static BOOL pipe_ntlmssp_auth_bind(pipes_struct *p, prs_struct *rpc_in_p,					RPC_HDR_AUTH *pauth_info, prs_struct *pout_auth){	RPC_HDR_AUTH auth_info;        DATA_BLOB blob;	DATA_BLOB response;        NTSTATUS status;	AUTH_NTLMSSP_STATE *a = NULL;	ZERO_STRUCT(blob);	ZERO_STRUCT(response);	/* Grab the NTLMSSP blob. */	blob = data_blob(NULL,p->hdr.auth_len);	if (!prs_copy_data_out((char *)blob.data, rpc_in_p, p->hdr.auth_len)) {		DEBUG(0,("pipe_ntlmssp_auth_bind: Failed to pull %u bytes - the NTLM auth header.\n",			(unsigned int)p->hdr.auth_len ));		goto err;	}	if (strncmp((char *)blob.data, "NTLMSSP", 7) != 0) {		DEBUG(0,("pipe_ntlmssp_auth_bind: Failed to read NTLMSSP in blob\n"));                goto err;        }	/* We have an NTLMSSP blob. */	status = auth_ntlmssp_start(&a);	if (!NT_STATUS_IS_OK(status)) {		DEBUG(0,("pipe_ntlmssp_auth_bind: auth_ntlmssp_start failed: %s\n",			nt_errstr(status) ));		goto err;	}	status = auth_ntlmssp_update(a, blob, &response);	if (!NT_STATUS_EQUAL(status, NT_STATUS_MORE_PROCESSING_REQUIRED)) {

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -