示例#1
0
static bool do_node_status(const char *name,
		int type,
		struct sockaddr_storage *pss)
{
	struct nmb_name nname;
	int count, i, j;
	struct node_status *addrs;
	struct node_status_extra extra;
	fstring cleanname;
	char addr[INET6_ADDRSTRLEN];
	NTSTATUS status;

	print_sockaddr(addr, sizeof(addr), pss);
	d_printf("Looking up status of %s\n",addr);
	make_nmb_name(&nname, name, type);
	status = node_status_query(talloc_tos(), &nname, pss,
				   &addrs, &count, &extra);
	if (NT_STATUS_IS_OK(status)) {
		for (i=0;i<count;i++) {
			pull_ascii_fstring(cleanname, addrs[i].name);
			for (j=0;cleanname[j];j++) {
				if (!isprint((int)cleanname[j])) {
					cleanname[j] = '.';
				}
			}
			d_printf("\t%-15s <%02x> - %s\n",
			       cleanname,addrs[i].type,
			       node_status_flags(addrs[i].flags));
		}
		d_printf("\n\tMAC Address = %02X-%02X-%02X-%02X-%02X-%02X\n",
				extra.mac_addr[0], extra.mac_addr[1],
				extra.mac_addr[2], extra.mac_addr[3],
				extra.mac_addr[4], extra.mac_addr[5]);
		d_printf("\n");
		TALLOC_FREE(addrs);
		return true;
	} else {
		d_printf("No reply from %s\n\n",addr);
		return false;
	}
}
示例#2
0
static void do_node_status(int fd,
		const char *name,
		int type,
		struct sockaddr_storage *pss)
{
	struct nmb_name nname;
	int count, i, j;
	NODE_STATUS_STRUCT *status;
	struct node_status_extra extra;
	fstring cleanname;
	char addr[INET6_ADDRSTRLEN];

	print_sockaddr(addr, sizeof(addr), pss);
	d_printf("Looking up status of %s\n",addr);
	make_nmb_name(&nname, name, type);
	status = node_status_query(fd, &nname, pss, &count, &extra);
	if (status) {
		for (i=0;i<count;i++) {
			pull_ascii_fstring(cleanname, status[i].name);
			for (j=0;cleanname[j];j++) {
				if (!isprint((int)cleanname[j])) {
					cleanname[j] = '.';
				}
			}
			d_printf("\t%-15s <%02x> - %s\n",
			       cleanname,status[i].type,
			       node_status_flags(status[i].flags));
		}
		d_printf("\n\tMAC Address = %02X-%02X-%02X-%02X-%02X-%02X\n",
				extra.mac_addr[0], extra.mac_addr[1],
				extra.mac_addr[2], extra.mac_addr[3],
				extra.mac_addr[4], extra.mac_addr[5]);
		d_printf("\n");
		SAFE_FREE(status);
	} else {
		d_printf("No reply from %s\n\n",addr);
	}
}
void process_host_announce(struct subnet_record *subrec, struct packet_struct *p, char *buf)
{
	struct dgram_packet *dgram = &p->packet.dgram;
	int ttl = IVAL(buf,1)/1000;
	unstring announce_name;
	uint32 servertype = IVAL(buf,23);
	fstring comment;
	struct work_record *work;
	struct server_record *servrec;
	unstring work_name;
	unstring source_name;

	START_PROFILE(host_announce);

	pull_ascii_fstring(comment, buf+31);
  
	pull_ascii_nstring(announce_name, sizeof(announce_name), buf+5);
	pull_ascii_nstring(source_name, sizeof(source_name), dgram->source_name.name);

	DEBUG(3,("process_host_announce: from %s<%02x> IP %s to \
%s for server %s.\n", source_name, source_name[15], inet_ntoa(p->ip),
			nmb_namestr(&dgram->dest_name),announce_name));

	DEBUG(5,("process_host_announce: ttl=%d server type=%08x comment=%s\n",
		ttl, servertype,comment));

	/* Filter servertype to remove impossible bits. */
	servertype &= ~(SV_TYPE_LOCAL_LIST_ONLY|SV_TYPE_DOMAIN_ENUM);

	/* A host announcement must be sent to the name WORKGROUP<1d>. */
	if(dgram->dest_name.name_type != 0x1d) {
		DEBUG(2,("process_host_announce: incorrect name type for destination from IP %s \
(was %02x) should be 0x1d. Allowing packet anyway.\n",
			inet_ntoa(p->ip), dgram->dest_name.name_type));
		/* Change it so it was. */
		dgram->dest_name.name_type = 0x1d;
	}

	/* For a host announce the workgroup name is the destination name. */
	pull_ascii_nstring(work_name, sizeof(work_name), dgram->dest_name.name);

	/*
	 * Syntax servers version 5.1 send HostAnnounce packets to
	 * *THE WRONG NAME*. They send to LOCAL_MASTER_BROWSER_NAME<00>
	 * instead of WORKGROUP<1d> name. So to fix this we check if
	 * the workgroup name is our own name, and if so change it
	 * to be our primary workgroup name.
	 */

	if(strequal(work_name, global_myname()))
		unstrcpy(work_name,lp_workgroup());

	/*
	 * We are being very agressive here in adding a workgroup
	 * name on the basis of a host announcing itself as being
	 * in that workgroup. Maybe we should wait for the workgroup
	 * announce instead ? JRA.
	 */

	work = find_workgroup_on_subnet(subrec, work_name);

	if(servertype != 0) {
		if (work ==NULL ) {
			/* We have no record of this workgroup. Add it. */
			if((work = create_workgroup_on_subnet(subrec, work_name, ttl))==NULL)
				goto done;
		}
  
		if((servrec = find_server_in_workgroup( work, announce_name))==NULL) {
			/* If this server is not already in the workgroup, add it. */
			create_server_on_workgroup(work, announce_name, 
				servertype|SV_TYPE_LOCAL_LIST_ONLY, 
				ttl, comment);
		} else {
			/* Update the record. */
			servrec->serv.type = servertype|SV_TYPE_LOCAL_LIST_ONLY;
			update_server_ttl( servrec, ttl);
			fstrcpy(servrec->serv.comment,comment);
		}
	} else {
		/*
		 * This server is announcing it is going down. Remove it from the 
		 * workgroup.
		 */
		if(!is_myname(announce_name) && (work != NULL) &&
				((servrec = find_server_in_workgroup( work, announce_name))!=NULL)) {
			remove_server_from_workgroup( work, servrec);
		}
	}

	subrec->work_changed = True;
done:

	END_PROFILE(host_announce);
}
void process_local_master_announce(struct subnet_record *subrec, struct packet_struct *p, char *buf)
{
	struct dgram_packet *dgram = &p->packet.dgram;
	int ttl = IVAL(buf,1)/1000;
	unstring server_name;
	uint32 servertype = IVAL(buf,23);
	fstring comment;
	unstring work_name;
	struct work_record *work;
	struct server_record *servrec;
	unstring source_name;

	START_PROFILE(local_master_announce);

	pull_ascii_nstring(server_name,sizeof(server_name),buf+5);
	pull_ascii_fstring(comment, buf+31);
	pull_ascii_nstring(source_name, sizeof(source_name), dgram->source_name.name);
	pull_ascii_nstring(work_name, sizeof(work_name), dgram->dest_name.name);

	DEBUG(3,("process_local_master_announce: from %s<%02x> IP %s to \
%s for server %s.\n", source_name, source_name[15], inet_ntoa(p->ip),
		nmb_namestr(&dgram->dest_name),server_name));

	DEBUG(5,("process_local_master_announce: ttl=%d server type=%08x comment=%s\n",
		ttl, servertype, comment));

	/* A local master announcement must be sent to the name WORKGROUP<1e>. */
	if(dgram->dest_name.name_type != 0x1e) {
		DEBUG(0,("process_local_master_announce: incorrect name type for destination from IP %s \
(was %02x) should be 0x1e. Ignoring packet.\n",
			inet_ntoa(p->ip), dgram->dest_name.name_type));
		goto done;
	}

	/* Filter servertype to remove impossible bits. */
	servertype &= ~(SV_TYPE_LOCAL_LIST_ONLY|SV_TYPE_DOMAIN_ENUM);

	/* For a local master announce the workgroup name is the destination name. */

	if ((work = find_workgroup_on_subnet(subrec, work_name))==NULL) {
		/* Don't bother adding if it's a local master release announce. */
		if(servertype == 0)
			goto done;

		/* We have no record of this workgroup. Add it. */
		if((work = create_workgroup_on_subnet(subrec, work_name, ttl))==NULL)
			goto done;
	}

	/* If we think we're the local master browser for this workgroup,
		we should never have got this packet. We don't see our own
		packets.
	*/
	if(AM_LOCAL_MASTER_BROWSER(work)) {
		DEBUG(0,("process_local_master_announce: Server %s at IP %s is announcing itself as \
a local master browser for workgroup %s and we think we are master. Forcing election.\n",
			server_name, inet_ntoa(p->ip), work_name));

		/* Samba nmbd versions 1.9.17 to 1.9.17p4 have a bug in that when
		 they have become a local master browser once, they will never
		 stop sending local master announcements. To fix this we send
		 them a reset browser packet, with level 0x2 on the __SAMBA__
		 name that only they should be listening to. */
   
		send_browser_reset( 0x2, "__SAMBA__" , 0x20, p->ip);

		/* We should demote ourself and force an election. */

		unbecome_local_master_browser( subrec, work, True);

		/* The actual election requests are handled in nmbd_election.c */
		goto done;
	}  

	/* Find the server record on this workgroup. If it doesn't exist, add it. */

	if(servertype != 0) {
		if((servrec = find_server_in_workgroup( work, server_name))==NULL) {
			/* If this server is not already in the workgroup, add it. */
			create_server_on_workgroup(work, server_name, 
				servertype|SV_TYPE_LOCAL_LIST_ONLY, 
				ttl, comment);
		} else {
			/* Update the record. */
			servrec->serv.type = servertype|SV_TYPE_LOCAL_LIST_ONLY;
			update_server_ttl(servrec, ttl);
			fstrcpy(servrec->serv.comment,comment);
		}
	
		set_workgroup_local_master_browser_name( work, server_name );
	} else {
		/*
		 * This server is announcing it is going down. Remove it from the
		 * workgroup.
		 */
		if(!is_myname(server_name) && (work != NULL) &&
				((servrec = find_server_in_workgroup( work, server_name))!=NULL)) {
			remove_server_from_workgroup( work, servrec);
		}
	}

	subrec->work_changed = True;
done:

	END_PROFILE(local_master_announce);
}
示例#5
0
static BOOL cli_get_ea_list(struct cli_state *cli,
		uint16 setup, char *param, unsigned int param_len,
		TALLOC_CTX *ctx,
		size_t *pnum_eas,
		struct ea_struct **pea_list)
{
	unsigned int data_len = 0;
	unsigned int rparam_len, rdata_len;
	char *rparam=NULL, *rdata=NULL;
	char *p;
	size_t ea_size;
	size_t num_eas;
	BOOL ret = False;
	struct ea_struct *ea_list;

	*pnum_eas = 0;
	*pea_list = NULL;

	if (!cli_send_trans(cli, SMBtrans2,
			NULL,           /* Name */
			-1, 0,          /* fid, flags */
			&setup, 1, 0,   /* setup, length, max */
			param, param_len, 10, /* param, length, max */
			NULL, data_len, cli->max_xmit /* data, length, max */
				)) {
		return False;
	}

	if (!cli_receive_trans(cli, SMBtrans2,
			&rparam, &rparam_len,
			&rdata, &rdata_len)) {
		return False;
	}

	if (!rdata || rdata_len < 4) {
		goto out;
	}

	ea_size = (size_t)IVAL(rdata,0);
	if (ea_size > rdata_len) {
		goto out;
	}

	if (ea_size == 0) {
		/* No EA's present. */
		ret = True;
		goto out;
	}

	p = rdata + 4;
	ea_size -= 4;

	/* Validate the EA list and count it. */
	for (num_eas = 0; ea_size >= 4; num_eas++) {
		unsigned int ea_namelen = CVAL(p,1);
		unsigned int ea_valuelen = SVAL(p,2);
		if (ea_namelen == 0) {
			goto out;
		}
		if (4 + ea_namelen + 1 + ea_valuelen > ea_size) {
			goto out;
		}
		ea_size -= 4 + ea_namelen + 1 + ea_valuelen;
		p += 4 + ea_namelen + 1 + ea_valuelen;
	}

	if (num_eas == 0) {
		ret = True;
		goto out;
	}

	*pnum_eas = num_eas;
	if (!pea_list) {
		/* Caller only wants number of EA's. */
		ret = True;
		goto out;
	}

	ea_list = (struct ea_struct *)talloc(ctx, num_eas*sizeof(struct ea_struct));
	if (!ea_list) {
		goto out;
	}

	ea_size = (size_t)IVAL(rdata,0);
	p = rdata + 4;

	for (num_eas = 0; num_eas < *pnum_eas; num_eas++ ) {
		struct ea_struct *ea = &ea_list[num_eas];
		fstring unix_ea_name;
		unsigned int ea_namelen = CVAL(p,1);
		unsigned int ea_valuelen = SVAL(p,2);

		ea->flags = CVAL(p,0);
		unix_ea_name[0] = '\0';
		pull_ascii_fstring(unix_ea_name, p + 4);
		ea->name = talloc_strdup(ctx, unix_ea_name);
		/* Ensure the value is null terminated (in case it's a string). */
		ea->value = data_blob_talloc(ctx, NULL, ea_valuelen + 1);
		if (!ea->value.data) {
			goto out;
		}
		if (ea_valuelen) {
			memcpy(ea->value.data, p+4+ea_namelen+1, ea_valuelen);
		}
		ea->value.data[ea_valuelen] = 0;
		ea->value.length--;
		p += 4 + ea_namelen + 1 + ea_valuelen;
	}

	*pea_list = ea_list;
	ret = True;

 out :

	SAFE_FREE(rdata);
	SAFE_FREE(rparam);
	return ret;
}
示例#6
0
文件: srv_pipe.c 项目: hajuuk/R7000
static BOOL api_pipe_ntlmssp_verify(pipes_struct *p, RPC_AUTH_NTLMSSP_RESP *ntlmssp_resp)
{
	uchar lm_owf[24];
	uchar nt_owf[128];
	int nt_pw_len;
	int lm_pw_len;
	fstring user_name;
	fstring domain;
	fstring wks;

	NTSTATUS nt_status;

	struct auth_context *auth_context = NULL;
	auth_usersupplied_info *user_info = NULL;
	auth_serversupplied_info *server_info = NULL;

	DEBUG(5,("api_pipe_ntlmssp_verify: checking user details\n"));

	memset(p->user_name, '\0', sizeof(p->user_name));
	memset(p->pipe_user_name, '\0', sizeof(p->pipe_user_name));
	memset(p->domain, '\0', sizeof(p->domain));
	memset(p->wks, '\0', sizeof(p->wks));

	/* Set up for non-authenticated user. */
	delete_nt_token(&p->pipe_user.nt_user_token);
	p->pipe_user.ngroups = 0;
	SAFE_FREE( p->pipe_user.groups);

	/* 
	 * Setup an empty password for a guest user.
	 */

	/*
	 * We always negotiate UNICODE.
	 */

	if (p->ntlmssp_chal_flags & NTLMSSP_NEGOTIATE_UNICODE) {
		rpcstr_pull(user_name, ntlmssp_resp->user, sizeof(fstring), ntlmssp_resp->hdr_usr.str_str_len*2, 0 );
		rpcstr_pull(domain, ntlmssp_resp->domain, sizeof(fstring), ntlmssp_resp->hdr_domain.str_str_len*2, 0);
		rpcstr_pull(wks, ntlmssp_resp->wks, sizeof(fstring), ntlmssp_resp->hdr_wks.str_str_len*2, 0);
	} else {
		pull_ascii_fstring(user_name, ntlmssp_resp->user);
		pull_ascii_fstring(domain, ntlmssp_resp->domain);
		pull_ascii_fstring(wks, ntlmssp_resp->wks);
	}

	DEBUG(5,("user: %s domain: %s wks: %s\n", user_name, domain, wks));

	nt_pw_len = MIN(sizeof(nt_owf), ntlmssp_resp->hdr_nt_resp.str_str_len);
	lm_pw_len = MIN(sizeof(lm_owf), ntlmssp_resp->hdr_lm_resp.str_str_len);

	memcpy(lm_owf, ntlmssp_resp->lm_resp, sizeof(lm_owf));
	memcpy(nt_owf, ntlmssp_resp->nt_resp, nt_pw_len);

#ifdef DEBUG_PASSWORD
	DEBUG(100,("lm, nt owfs, chal\n"));
	dump_data(100, (char *)lm_owf, sizeof(lm_owf));
	dump_data(100, (char *)nt_owf, nt_pw_len);
	dump_data(100, (char *)p->challenge, 8);
#endif

	/*
	 * Allow guest access. Patch from Shirish Kalele <*****@*****.**>.
	 */

	if (*user_name) {

	 	/* 
		 * Do the length checking only if user is not NULL.
		 */

 		if (ntlmssp_resp->hdr_lm_resp.str_str_len == 0)
 			return False;
 		if (ntlmssp_resp->hdr_nt_resp.str_str_len == 0)
 			return False;
 		if (ntlmssp_resp->hdr_usr.str_str_len == 0)
 			return False;
 		if (ntlmssp_resp->hdr_domain.str_str_len == 0)
 			return False;
 		if (ntlmssp_resp->hdr_wks.str_str_len == 0)
 			return False;

	}
	
	make_auth_context_fixed(&auth_context, (uchar*)p->challenge);

	if (!make_user_info_netlogon_network(&user_info, 
					     user_name, domain, wks,
					     lm_owf, lm_pw_len, 
					     nt_owf, nt_pw_len)) {
		DEBUG(0,("make_user_info_netlogon_network failed!  Failing authenticaion.\n"));
		return False;
	}
	
	nt_status = auth_context->check_ntlm_password(auth_context, user_info, &server_info); 
	
	(auth_context->free)(&auth_context);
	free_user_info(&user_info);
	
	p->ntlmssp_auth_validated = NT_STATUS_IS_OK(nt_status);
	
	if (!p->ntlmssp_auth_validated) {
		DEBUG(1,("api_pipe_ntlmssp_verify: User [%s]\\[%s] from machine %s \
failed authentication on named pipe %s.\n", domain, user_name, wks, p->name ));
		free_server_info(&server_info);
		return False;
	}