Example #1
0
/*
  reply to a ADS style GETDC request
 */
static void nbtd_netlogon_samlogon(struct dgram_mailslot_handler *dgmslot,
				   struct nbtd_interface *iface,
				   struct nbt_dgram_packet *packet, 
				   const struct socket_address *src,
				   struct nbt_netlogon_packet *netlogon)
{
	struct nbt_name *name = &packet->data.msg.dest_name;
	struct nbtd_interface *reply_iface = nbtd_find_reply_iface(iface, src->addr, false);
	struct ldb_context *samctx;
	const char *my_ip = reply_iface->ip_address; 
	struct dom_sid *sid;
	struct nbt_netlogon_response netlogon_response;
	NTSTATUS status;

	if (!my_ip) {
		DEBUG(0, ("Could not obtain own IP address for datagram socket\n"));
		return;
	}

	/* only answer getdc requests on the PDC or LOGON names */
	if (name->type != NBT_NAME_PDC && name->type != NBT_NAME_LOGON) {
		return;
	}

	samctx = iface->nbtsrv->sam_ctx;

	if (netlogon->req.logon.sid_size) {
		sid = &netlogon->req.logon.sid;
	} else {
		sid = NULL;
	}

	status = fill_netlogon_samlogon_response(samctx, packet, NULL, name->name, sid, NULL, 
						 netlogon->req.logon.user_name, netlogon->req.logon.acct_control, src->addr, 
						 netlogon->req.logon.nt_version, iface->nbtsrv->task->lp_ctx, &netlogon_response.data.samlogon, false);
	if (!NT_STATUS_IS_OK(status)) {
		DEBUG(2,("NBT netlogon query failed domain=%s sid=%s version=%d - %s\n",
			 name->name, dom_sid_string(packet, sid), netlogon->req.logon.nt_version, nt_errstr(status)));
		return;
	}

	netlogon_response.response_type = NETLOGON_SAMLOGON;

	packet->data.msg.dest_name.type = 0;

	dgram_mailslot_netlogon_reply(reply_iface->dgmsock, 
				      packet, 
				      lpcfg_netbios_name(iface->nbtsrv->task->lp_ctx),
				      netlogon->req.logon.mailslot_name,
				      &netlogon_response);
}
Example #2
0
/*
  handle incoming cldap requests
*/
void cldapd_netlogon_request(struct cldap_socket *cldap,
			     struct cldapd_server *cldapd,
			     TALLOC_CTX *tmp_ctx,
			     uint32_t message_id,
			     struct ldb_parse_tree *tree,
			     struct tsocket_address *src)
{
	unsigned int i;
	const char *domain = NULL;
	const char *host = NULL;
	const char *user = NULL;
	const char *domain_guid = NULL;
	struct dom_sid *domain_sid = NULL;
	int acct_control = -1;
	int version = -1;
	struct netlogon_samlogon_response netlogon;
	NTSTATUS status = NT_STATUS_INVALID_PARAMETER;

	if (tree->operation != LDB_OP_AND) goto failed;

	/* extract the query elements */
	for (i=0;i<tree->u.list.num_elements;i++) {
		struct ldb_parse_tree *t = tree->u.list.elements[i];
		if (t->operation != LDB_OP_EQUALITY) goto failed;
		if (strcasecmp(t->u.equality.attr, "DnsDomain") == 0) {
			domain = talloc_strndup(tmp_ctx, 
						(const char *)t->u.equality.value.data,
						t->u.equality.value.length);
		}
		if (strcasecmp(t->u.equality.attr, "Host") == 0) {
			host = talloc_strndup(tmp_ctx, 
					      (const char *)t->u.equality.value.data,
					      t->u.equality.value.length);
		}
		if (strcasecmp(t->u.equality.attr, "DomainGuid") == 0) {
			NTSTATUS enc_status;
			struct GUID guid;
			enc_status = ldap_decode_ndr_GUID(tmp_ctx, 
							  t->u.equality.value, &guid);
			if (NT_STATUS_IS_OK(enc_status)) {
				domain_guid = GUID_string(tmp_ctx, &guid);
			}
		}
		if (strcasecmp(t->u.equality.attr, "DomainSid") == 0) {
			enum ndr_err_code ndr_err;

			domain_sid = talloc(tmp_ctx, struct dom_sid);
			if (domain_sid == NULL) {
				goto failed;
			}
			ndr_err = ndr_pull_struct_blob(&t->u.equality.value,
						       domain_sid, domain_sid,
						       (ndr_pull_flags_fn_t)ndr_pull_dom_sid);
			if (!NDR_ERR_CODE_IS_SUCCESS(ndr_err)) {
				talloc_free(domain_sid);
				goto failed;
			}
		}
		if (strcasecmp(t->u.equality.attr, "User") == 0) {
			user = talloc_strndup(tmp_ctx, 
					      (const char *)t->u.equality.value.data,
					      t->u.equality.value.length);
		}
		if (strcasecmp(t->u.equality.attr, "NtVer") == 0 &&
		    t->u.equality.value.length == 4) {
			version = IVAL(t->u.equality.value.data, 0);
		}
		if (strcasecmp(t->u.equality.attr, "AAC") == 0 &&
		    t->u.equality.value.length == 4) {
			acct_control = IVAL(t->u.equality.value.data, 0);
		}
	}

	if ((domain == NULL) && (domain_guid == NULL) && (domain_sid == NULL)) {
		domain = lpcfg_dnsdomain(cldapd->task->lp_ctx);
	}

	if (version == -1) {
		goto failed;
	}

	DEBUG(5,("cldap netlogon query domain=%s host=%s user=%s version=%d guid=%s\n",
		 domain, host, user, version, domain_guid));

	status = fill_netlogon_samlogon_response(cldapd->samctx, tmp_ctx,
						 domain, NULL, domain_sid,
						 domain_guid,
						 user, acct_control,
						 tsocket_address_inet_addr_string(src, tmp_ctx),
						 version, cldapd->task->lp_ctx,
						 &netlogon, false);
	if (!NT_STATUS_IS_OK(status)) {
		goto failed;
	}

	status = cldap_netlogon_reply(cldap, message_id, src, version, &netlogon);
	if (!NT_STATUS_IS_OK(status)) {
		goto failed;
	}

	return;
	
failed:
	DEBUG(2,("cldap netlogon query failed domain=%s host=%s version=%d - %s\n",
		 domain, host, version, nt_errstr(status)));
	cldap_empty_reply(cldap, message_id, src);
}
Example #3
0
/*
  reply to a ADS style GETDC request
 */
static NTSTATUS nbtd_netlogon_samlogon(
	struct nbtd_server *nbtsrv,
	struct nbt_name *dst_name,
	const struct socket_address *src,
	struct nbt_netlogon_packet *netlogon,
	TALLOC_CTX *mem_ctx,
	struct nbt_netlogon_response **presponse,
	char **preply_mailslot)
{
	struct ldb_context *samctx;
	struct dom_sid *sid = NULL;
	struct nbt_netlogon_response *response = NULL;
	char *reply_mailslot = NULL;
	NTSTATUS status;

	/* only answer getdc requests on the PDC or LOGON names */
	if ((dst_name->type != NBT_NAME_PDC) &&
	    (dst_name->type != NBT_NAME_LOGON)) {
		return NT_STATUS_NOT_SUPPORTED;
	}

	samctx = nbtsrv->sam_ctx;

	if (netlogon->req.logon.sid_size != 0) {
		sid = &netlogon->req.logon.sid;
	}

	reply_mailslot = talloc_strdup(
		mem_ctx, netlogon->req.logon.mailslot_name);
	if (reply_mailslot == NULL) {
		return NT_STATUS_NO_MEMORY;
	}

	response = talloc_zero(mem_ctx, struct nbt_netlogon_response);
	if (response == NULL) {
		TALLOC_FREE(reply_mailslot);
		return NT_STATUS_NO_MEMORY;
	}
	response->response_type = NETLOGON_SAMLOGON;

	status = fill_netlogon_samlogon_response(
		samctx, response, NULL, dst_name->name, sid, NULL,
		netlogon->req.logon.user_name,
		netlogon->req.logon.acct_control, src->addr,
		netlogon->req.logon.nt_version, nbtsrv->task->lp_ctx,
		&response->data.samlogon, false);
	if (!NT_STATUS_IS_OK(status)) {
		char buf[DOM_SID_STR_BUFLEN];
		dom_sid_string_buf(sid, buf, sizeof(buf));

		DBG_NOTICE("NBT netlogon query failed domain=%s sid=%s "
			   "version=%d - %s\n", dst_name->name, buf,
			   netlogon->req.logon.nt_version, nt_errstr(status));
		TALLOC_FREE(reply_mailslot);
		TALLOC_FREE(response);
		return status;
	}

	*presponse = response;
	*preply_mailslot = reply_mailslot;
	return NT_STATUS_OK;
}