コード例 #1
0
ファイル: wrepl_server.c プロジェクト: AllardJ/Tomato
/*
 update the wins_owner_table max_version, if the given version is the highest version
 if no entry for the wins_owner exists yet, create one
*/
NTSTATUS wreplsrv_add_table(struct wreplsrv_service *service,
			    TALLOC_CTX *mem_ctx, struct wreplsrv_owner **_table,
			    const char *wins_owner, uint64_t version)
{
	struct wreplsrv_owner *table = *_table;
	struct wreplsrv_owner *cur;

	if (!wins_owner || strcmp(wins_owner, "0.0.0.0") == 0) {
		wins_owner = service->wins_db->local_owner;
	}

	cur = wreplsrv_find_owner(service, table, wins_owner);

	/* if it doesn't exists yet, create one */
	if (!cur) {
		cur = talloc_zero(mem_ctx, struct wreplsrv_owner);
		NT_STATUS_HAVE_NO_MEMORY(cur);

		cur->owner.address	= talloc_strdup(cur, wins_owner);
		NT_STATUS_HAVE_NO_MEMORY(cur->owner.address);
		cur->owner.min_version	= 0;
		cur->owner.max_version	= 0;
		cur->owner.type		= 1; /* don't know why this is always 1 */

		cur->partner		= wreplsrv_find_partner(service, wins_owner);

		DLIST_ADD_END(table, cur, struct wreplsrv_owner *);
		*_table = table;
	}
コード例 #2
0
ファイル: wrepl_in_connection.c プロジェクト: AIdrifter/samba
/*
  called when we get a new connection
*/
static void wreplsrv_accept(struct stream_connection *conn)
{
	struct wreplsrv_service *service = talloc_get_type(conn->private_data, struct wreplsrv_service);
	struct wreplsrv_in_connection *wrepl_conn;
	struct tsocket_address *peer_addr;
	char *peer_ip;
	struct tevent_req *subreq;
	int rc;

	wrepl_conn = talloc_zero(conn, struct wreplsrv_in_connection);
	if (wrepl_conn == NULL) {
		stream_terminate_connection(conn,
					    "wreplsrv_accept: out of memory");
		return;
	}

	wrepl_conn->send_queue = tevent_queue_create(conn, "wrepl_accept");
	if (wrepl_conn->send_queue == NULL) {
		stream_terminate_connection(conn,
					    "wrepl_accept: out of memory");
		return;
	}

	TALLOC_FREE(conn->event.fde);

	rc = tstream_bsd_existing_socket(wrepl_conn,
					 socket_get_fd(conn->socket),
					 &wrepl_conn->tstream);
	if (rc < 0) {
		stream_terminate_connection(conn,
					    "wrepl_accept: out of memory");
		return;
	}
	socket_set_flags(conn->socket, SOCKET_FLAG_NOCLOSE);

	wrepl_conn->conn = conn;
	wrepl_conn->service = service;

	peer_addr = conn->remote_address;

	if (!tsocket_address_is_inet(peer_addr, "ipv4")) {
		DEBUG(0,("wreplsrv_accept: non ipv4 peer addr '%s'\n",
			tsocket_address_string(peer_addr, wrepl_conn)));
		wreplsrv_terminate_in_connection(wrepl_conn, "wreplsrv_accept: "
				"invalid peer IP");
		return;
	}

	peer_ip = tsocket_address_inet_addr_string(peer_addr, wrepl_conn);
	if (peer_ip == NULL) {
		wreplsrv_terminate_in_connection(wrepl_conn, "wreplsrv_accept: "
				"could not convert peer IP into a string");
		return;
	}

	wrepl_conn->partner = wreplsrv_find_partner(service, peer_ip);
	irpc_add_name(conn->msg_ctx, "wreplsrv_connection");

	/*
	 * The wrepl pdu's has the length as 4 byte (initial_read_size),
	 * packet_full_request_u32 provides the pdu length then.
	 */
	subreq = tstream_read_pdu_blob_send(wrepl_conn,
					    wrepl_conn->conn->event.ctx,
					    wrepl_conn->tstream,
					    4, /* initial_read_size */
					    packet_full_request_u32,
					    wrepl_conn);
	if (subreq == NULL) {
		wreplsrv_terminate_in_connection(wrepl_conn, "wrepl_accept: "
				"no memory for tstream_read_pdu_blob_send");
		return;
	}
	tevent_req_set_callback(subreq, wreplsrv_call_loop, wrepl_conn);
}
コード例 #3
0
ファイル: wrepl_server.c プロジェクト: AllardJ/Tomato
/*
  load our replication partners
*/
NTSTATUS wreplsrv_load_partners(struct wreplsrv_service *service)
{
	struct wreplsrv_partner *partner;
	struct ldb_result *res = NULL;
	int ret;
	TALLOC_CTX *tmp_ctx;
	int i;
	uint64_t new_seqnumber;

	new_seqnumber = wins_config_db_get_seqnumber(service->config.ldb);

	/* if it's not the first run and nothing changed we're done */
	if (service->config.seqnumber != 0 && service->config.seqnumber == new_seqnumber) {
		return NT_STATUS_OK;
	}

	tmp_ctx = talloc_new(service);
	NT_STATUS_HAVE_NO_MEMORY(tmp_ctx);

	service->config.seqnumber = new_seqnumber;

	/* find the record in the WINS database */
	ret = ldb_search(service->config.ldb, tmp_ctx, &res,
			 ldb_dn_new(tmp_ctx, service->config.ldb, "CN=PARTNERS"),
			 LDB_SCOPE_SUBTREE, NULL, "(objectClass=wreplPartner)");
	if (ret != LDB_SUCCESS) goto failed;

	/* first disable all existing partners */
	for (partner=service->partners; partner; partner = partner->next) {
		partner->type = WINSREPL_PARTNER_NONE;
	}

	for (i=0; i < res->count; i++) {
		const char *address;

		address	= ldb_msg_find_attr_as_string(res->msgs[i], "address", NULL);
		if (!address) {
			goto failed;
		}

		partner = wreplsrv_find_partner(service, address);
		if (partner) {
			if (partner->name != partner->address) {
				talloc_free(discard_const(partner->name));
			}
			partner->name = NULL;
			talloc_free(discard_const(partner->our_address));
			partner->our_address = NULL;

			/* force rescheduling of pulling */
			partner->pull.next_run = timeval_zero();
		} else {
			partner = talloc_zero(service, struct wreplsrv_partner);
			if (partner == NULL) goto failed;

			partner->service = service;
			partner->address = address;
			talloc_steal(partner, partner->address);

			DLIST_ADD_END(service->partners, partner, struct wreplsrv_partner *);
		}

		partner->name			= ldb_msg_find_attr_as_string(res->msgs[i], "name", partner->address);
		talloc_steal(partner, partner->name);
		partner->our_address		= ldb_msg_find_attr_as_string(res->msgs[i], "ourAddress", NULL);
		talloc_steal(partner, partner->our_address);

		partner->type			= ldb_msg_find_attr_as_uint(res->msgs[i], "type", WINSREPL_PARTNER_BOTH);
		partner->pull.interval		= ldb_msg_find_attr_as_uint(res->msgs[i], "pullInterval",
								    WINSREPL_DEFAULT_PULL_INTERVAL);
		partner->pull.retry_interval	= ldb_msg_find_attr_as_uint(res->msgs[i], "pullRetryInterval",
								    WINSREPL_DEFAULT_PULL_RETRY_INTERVAL);
		partner->push.change_count	= ldb_msg_find_attr_as_uint(res->msgs[i], "pushChangeCount",
								    WINSREPL_DEFAULT_PUSH_CHANGE_COUNT);
		partner->push.use_inform	= ldb_msg_find_attr_as_uint(res->msgs[i], "pushUseInform", true);

		DEBUG(3,("wreplsrv_load_partners: found partner: %s type: 0x%X\n",
			partner->address, partner->type));
	}

	DEBUG(2,("wreplsrv_load_partners: %u partners found: wins_config_db seqnumber %llu\n",
		res->count, (unsigned long long)service->config.seqnumber));

	talloc_free(tmp_ctx);
	return NT_STATUS_OK;
failed:
	talloc_free(tmp_ctx);
	return NT_STATUS_FOOBAR;
}