Exemple #1
0
/*
  register a ndr interface table
*/
NTSTATUS ndr_table_register(const struct ndr_interface_table *table)
{
	struct ndr_interface_list *l;

	for (l = ndr_interfaces; l; l = l->next) {
		if (GUID_equal(&table->syntax_id.uuid, &l->table->syntax_id.uuid)) {
			DEBUG(0, ("Attempt to register interface %s which has the "
				  "same UUID as already registered interface %s\n", 
				  table->name, l->table->name));
			return NT_STATUS_OBJECT_NAME_COLLISION;
		}
	}

	l = talloc(talloc_autofree_context(), struct ndr_interface_list);
	l->table = table;

	DLIST_ADD(ndr_interfaces, l);

  	return NT_STATUS_OK;
}
Exemple #2
0
/**
  find an internal handle given a wire handle. If the wire handle is NULL then
  allocate a new handle
*/
_PUBLIC_ struct dcesrv_handle *dcesrv_handle_fetch(
					  struct dcesrv_connection_context *context, 
					  struct policy_handle *p,
					  uint8_t handle_type)
{
	struct dcesrv_handle *h;
	struct dom_sid *sid;

	sid = context->conn->auth_state.session_info->security_token->user_sid;

	if (policy_handle_empty(p)) {
		/* TODO: we should probably return a NULL handle here */
		return dcesrv_handle_new(context, handle_type);
	}

	for (h=context->assoc_group->handles; h; h=h->next) {
		if (h->wire_handle.handle_type == p->handle_type &&
		    GUID_equal(&p->uuid, &h->wire_handle.uuid)) {
			if (handle_type != DCESRV_HANDLE_ANY &&
			    p->handle_type != handle_type) {
				DEBUG(0,("client gave us the wrong handle type (%d should be %d)\n",
					 p->handle_type, handle_type));
				return NULL;
			}
			if (!dom_sid_equal(h->sid, sid)) {
				DEBUG(0,(__location__ ": Attempt to use invalid sid %s - %s\n",
					 dom_sid_string(context, h->sid),
					 dom_sid_string(context, sid)));
				return NULL;
			}
			if (h->iface != context->iface) {
				DEBUG(0,(__location__ ": Attempt to use invalid iface\n"));
				return NULL;
			}
			return h;
		}
	}

	return NULL;
}
Exemple #3
0
static bool test_parse_check_results(struct torture_context *tctx)
{
	struct dcerpc_binding *b;
	struct GUID uuid;

	torture_assert_ntstatus_ok(tctx, 
				   GUID_from_string("308FB580-1EB2-11CA-923B-08002B1075A7", &uuid),
				   "parsing uuid");

	torture_assert_ntstatus_ok(tctx, dcerpc_parse_binding(tctx, "ncacn_np:$SERVER", &b), "parse");
	torture_assert(tctx, b->transport == NCACN_NP, "ncacn_np expected");
	torture_assert_ntstatus_ok(tctx, dcerpc_parse_binding(tctx, "ncacn_ip_tcp:$SERVER", &b), "parse");
	torture_assert(tctx, b->transport == NCACN_IP_TCP, "ncacn_ip_tcp expected");
	torture_assert_ntstatus_ok(tctx, dcerpc_parse_binding(tctx, "ncacn_np:$SERVER[rpcecho]", &b), "parse");
	torture_assert_str_equal(tctx, b->endpoint, "rpcecho", "endpoint");
	torture_assert_ntstatus_ok(tctx, dcerpc_parse_binding(tctx, "ncacn_np:$SERVER[/pipe/rpcecho]", &b), "parse");
	torture_assert_ntstatus_ok(tctx, dcerpc_parse_binding(tctx, "ncacn_np:$SERVER[/pipe/rpcecho,sign,seal]", &b), "parse");
	torture_assert(tctx, b->flags == DCERPC_SIGN+DCERPC_SEAL, "sign+seal flags");
	torture_assert_str_equal(tctx, b->endpoint, "/pipe/rpcecho", "endpoint");
	torture_assert_ntstatus_ok(tctx, dcerpc_parse_binding(tctx, "ncacn_np:$SERVER[,sign]", &b), "parse");
	torture_assert_ntstatus_ok(tctx, dcerpc_parse_binding(tctx, "ncacn_ip_tcp:$SERVER[,sign]", &b), "parse");
	torture_assert(tctx, b->endpoint == NULL, "endpoint");
	torture_assert(tctx, b->flags == DCERPC_SIGN, "sign flag");
	torture_assert_ntstatus_ok(tctx, dcerpc_parse_binding(tctx, "ncalrpc:", &b), "parse");
	torture_assert(tctx, b->transport == NCALRPC, "ncalrpc expected");
	torture_assert_ntstatus_ok(tctx, dcerpc_parse_binding(tctx, 
		"308FB580-1EB2-11CA-923B-08002B1075A7@ncacn_np:$SERVER", &b), "parse");
	torture_assert(tctx, GUID_equal(&b->object.uuid, &uuid), "object uuid");
	torture_assert_int_equal(tctx, b->object.if_version, 0, "object version");
	torture_assert_ntstatus_ok(tctx, dcerpc_parse_binding(tctx, 
		"308FB580-1EB2-11CA-923B-08002B1075A7@ncacn_ip_tcp:$SERVER", &b), "parse");
	torture_assert_ntstatus_ok(tctx, dcerpc_parse_binding(tctx, "ncacn_ip_tcp:$SERVER[,sign,localaddress=192.168.1.1]", &b), "parse");
	torture_assert(tctx, b->transport == NCACN_IP_TCP, "ncacn_ip_tcp expected");
	torture_assert(tctx, b->flags == (DCERPC_SIGN | DCERPC_LOCALADDRESS), "sign flag");
	torture_assert_str_equal(tctx, b->localaddress, "192.168.1.1", "localaddress");
	torture_assert_str_equal(tctx, "ncacn_ip_tcp:$SERVER[,sign,localaddress=192.168.1.1]",
				 dcerpc_binding_string(tctx, b), "back to string");

	return true;
}
Exemple #4
0
/*
 * Check if the UUID and if_version match to an interface.
 */
static bool interface_match(const struct dcesrv_iface *if1,
			    const struct dcesrv_iface *if2)
{
	return GUID_equal(&if1->syntax_id.uuid, &if2->syntax_id.uuid);
}
Exemple #5
0
/*
 * See if a uuid and if_version match to an interface
 */
static bool interface_match_by_uuid(const struct dcesrv_iface *iface,
				    const struct GUID *uuid)
{
	return GUID_equal(&iface->syntax_id.uuid, uuid);
}
Exemple #6
0
const char *epm_floor_string(TALLOC_CTX *mem_ctx, struct epm_floor *epm_floor)
{
	struct dcerpc_syntax_id syntax;
	NTSTATUS status;

	switch(epm_floor->lhs.protocol) {
		case EPM_PROTOCOL_UUID:
			status = dcerpc_floor_get_lhs_data(epm_floor, &syntax);
			if (NT_STATUS_IS_OK(status)) {
				/* lhs is used: UUID */
				char *uuidstr;

				if (GUID_equal(&syntax.uuid, &ndr_transfer_syntax.uuid)) {
					return "NDR";
				} 

				if (GUID_equal(&syntax.uuid, &ndr64_transfer_syntax.uuid)) {
					return "NDR64";
				} 

				uuidstr = GUID_string(mem_ctx, &syntax.uuid);

				return talloc_asprintf(mem_ctx, " uuid %s/0x%02x", uuidstr, syntax.if_version);
			} else { /* IPX */
				return talloc_asprintf(mem_ctx, "IPX:%s", 
						data_blob_hex_string(mem_ctx, &epm_floor->rhs.uuid.unknown));
			}

		case EPM_PROTOCOL_NCACN:
			return "RPC-C";

		case EPM_PROTOCOL_NCADG:
			return "RPC";

		case EPM_PROTOCOL_NCALRPC:
			return "NCALRPC";

		case EPM_PROTOCOL_DNET_NSP:
			return "DNET/NSP";

		case EPM_PROTOCOL_IP:
			return talloc_asprintf(mem_ctx, "IP:%s", epm_floor->rhs.ip.ipaddr);

		case EPM_PROTOCOL_PIPE:
			return talloc_asprintf(mem_ctx, "PIPE:%s", epm_floor->rhs.pipe.path);

		case EPM_PROTOCOL_SMB:
			return talloc_asprintf(mem_ctx, "SMB:%s", epm_floor->rhs.smb.unc);

		case EPM_PROTOCOL_UNIX_DS:
			return talloc_asprintf(mem_ctx, "Unix:%s", epm_floor->rhs.unix_ds.path);

		case EPM_PROTOCOL_NETBIOS:
			return talloc_asprintf(mem_ctx, "NetBIOS:%s", epm_floor->rhs.netbios.name);

		case EPM_PROTOCOL_NETBEUI:
			return "NETBeui";

		case EPM_PROTOCOL_SPX:
			return "SPX";

		case EPM_PROTOCOL_NB_IPX:
			return "NB_IPX";

		case EPM_PROTOCOL_HTTP:
			return talloc_asprintf(mem_ctx, "HTTP:%d", epm_floor->rhs.http.port);

		case EPM_PROTOCOL_TCP:
			return talloc_asprintf(mem_ctx, "TCP:%d", epm_floor->rhs.tcp.port);

		case EPM_PROTOCOL_UDP:
			return talloc_asprintf(mem_ctx, "UDP:%d", epm_floor->rhs.udp.port);

		default:
			return talloc_asprintf(mem_ctx, "UNK(%02x):", epm_floor->lhs.protocol);
	}
}
Exemple #7
0
NTSTATUS smb2srv_open_recreate(struct smbXsrv_connection *conn,
			       struct auth_session_info *session_info,
			       uint64_t persistent_id,
			       const struct GUID *create_guid,
			       NTTIME now,
			       struct smbXsrv_open **_open)
{
	struct smbXsrv_open_table *table = conn->client->open_table;
	struct db_record *local_rec = NULL;
	struct smbXsrv_open *op = NULL;
	void *ptr = NULL;
	TDB_DATA val;
	uint32_t global_id = persistent_id & UINT32_MAX;
	uint64_t global_zeros = persistent_id & 0xFFFFFFFF00000000LLU;
	NTSTATUS status;
	struct security_token *current_token = NULL;

	if (session_info == NULL) {
		DEBUG(10, ("session_info=NULL\n"));
		return NT_STATUS_INVALID_HANDLE;
	}
	current_token = session_info->security_token;

	if (current_token == NULL) {
		DEBUG(10, ("current_token=NULL\n"));
		return NT_STATUS_INVALID_HANDLE;
	}

	if (global_zeros != 0) {
		DEBUG(10, ("global_zeros!=0\n"));
		return NT_STATUS_OBJECT_NAME_NOT_FOUND;
	}

	op = talloc_zero(table, struct smbXsrv_open);
	if (op == NULL) {
		return NT_STATUS_NO_MEMORY;
	}
	op->table = table;

	status = smbXsrv_open_global_lookup(table, global_id, op, &op->global);
	if (!NT_STATUS_IS_OK(status)) {
		TALLOC_FREE(op);
		DEBUG(10, ("smbXsrv_open_global_lookup returned %s\n",
			   nt_errstr(status)));
		return status;
	}

	/*
	 * If the provided create_guid is NULL, this means that
	 * the reconnect request was a v1 request. In that case
	 * we should skipt the create GUID verification, since
	 * it is valid to v1-reconnect a v2-opened handle.
	 */
	if ((create_guid != NULL) &&
	    !GUID_equal(&op->global->create_guid, create_guid))
	{
		TALLOC_FREE(op);
		return NT_STATUS_OBJECT_NAME_NOT_FOUND;
	}

	if (!security_token_is_sid(current_token, &op->global->open_owner)) {
		TALLOC_FREE(op);
		return NT_STATUS_OBJECT_NAME_NOT_FOUND;
	}

	if (!op->global->durable) {
		TALLOC_FREE(op);
		return NT_STATUS_OBJECT_NAME_NOT_FOUND;
	}

	if (table->local.num_opens >= table->local.max_opens) {
		TALLOC_FREE(op);
		return NT_STATUS_INSUFFICIENT_RESOURCES;
	}

	status = smbXsrv_open_local_allocate_id(table->local.db_ctx,
						table->local.lowest_id,
						table->local.highest_id,
						op,
						&local_rec,
						&op->local_id);
	if (!NT_STATUS_IS_OK(status)) {
		TALLOC_FREE(op);
		return status;
	}

	op->idle_time = now;
	op->status = NT_STATUS_FILE_CLOSED;

	op->global->open_volatile_id = op->local_id;
	op->global->server_id = messaging_server_id(conn->msg_ctx);

	ptr = op;
	val = make_tdb_data((uint8_t const *)&ptr, sizeof(ptr));
	status = dbwrap_record_store(local_rec, val, TDB_REPLACE);
	TALLOC_FREE(local_rec);
	if (!NT_STATUS_IS_OK(status)) {
		TALLOC_FREE(op);
		return status;
	}
	table->local.num_opens += 1;

	talloc_set_destructor(op, smbXsrv_open_destructor);

	status = smbXsrv_open_global_store(op->global);
	if (!NT_STATUS_IS_OK(status)) {
		TALLOC_FREE(op);
		return status;
	}

	if (CHECK_DEBUGLVL(10)) {
		struct smbXsrv_openB open_blob;

		ZERO_STRUCT(open_blob);
		open_blob.version = 0;
		open_blob.info.info0 = op;

		DEBUG(10,("smbXsrv_open_recreate: global_id (0x%08x) stored\n",
			 op->global->open_global_id));
		NDR_PRINT_DEBUG(smbXsrv_openB, &open_blob);
	}

	*_open = op;
	return NT_STATUS_OK;
}
Exemple #8
0
/*
  create a RID Set object for the specified DC
 */
static int ridalloc_create_rid_set_ntds(struct ldb_module *module, TALLOC_CTX *mem_ctx,
					struct ldb_dn *rid_manager_dn,
					struct ldb_dn *ntds_dn, struct ldb_dn **dn,
					struct ldb_request *parent)
{
	TALLOC_CTX *tmp_ctx = talloc_new(mem_ctx);
	struct ldb_dn *server_dn, *machine_dn, *rid_set_dn;
	int ret;
	struct ldb_message *msg;
	struct ldb_context *ldb = ldb_module_get_ctx(module);
	static const struct ridalloc_ridset_values o = {
		.alloc_pool	= UINT64_MAX,
		.prev_pool	= UINT64_MAX,
		.next_rid	= UINT32_MAX,
		.used_pool	= UINT32_MAX,
	};
	struct ridalloc_ridset_values n = {
		.alloc_pool	= 0,
		.prev_pool	= 0,
		.next_rid	= 0,
		.used_pool	= 0,
	};
	const char *no_attrs[] = { NULL };
	struct ldb_result *res;

	/*
	  steps:

	  find the machine object for the DC
	  construct the RID Set DN
	  load rIDAvailablePool to find next available set
	  modify RID Manager object to update rIDAvailablePool
	  add the RID Set object
	  link to the RID Set object in machine object
	 */

	server_dn = ldb_dn_get_parent(tmp_ctx, ntds_dn);
	if (!server_dn) {
		talloc_free(tmp_ctx);
		return ldb_module_oom(module);
	}

	ret = dsdb_module_reference_dn(module, tmp_ctx, server_dn, "serverReference", &machine_dn, parent);
	if (ret != LDB_SUCCESS) {
		ldb_asprintf_errstring(ldb, "Failed to find serverReference in %s - %s",
				       ldb_dn_get_linearized(server_dn), ldb_errstring(ldb));
		talloc_free(tmp_ctx);
		return ret;
	}

	rid_set_dn = ldb_dn_copy(tmp_ctx, machine_dn);
	if (rid_set_dn == NULL) {
		talloc_free(tmp_ctx);
		return ldb_module_oom(module);
	}

	if (! ldb_dn_add_child_fmt(rid_set_dn, "CN=RID Set")) {
		talloc_free(tmp_ctx);
		return ldb_module_oom(module);
	}

	/* grab a pool from the RID Manager object */
	ret = ridalloc_rid_manager_allocate(module, rid_manager_dn, &n.alloc_pool, parent);
	if (ret != LDB_SUCCESS) {
		talloc_free(tmp_ctx);
		return ret;
	}

	/* create the RID Set object */
	msg = ldb_msg_new(tmp_ctx);
	msg->dn = rid_set_dn;

	ret = ldb_msg_add_string(msg, "objectClass", "rIDSet");
	if (ret != LDB_SUCCESS) {
		talloc_free(tmp_ctx);
		return ret;
	}

	ret = ridalloc_set_ridset_values(module, msg, &o, &n);
	if (ret != LDB_SUCCESS) {
		talloc_free(tmp_ctx);
		return ret;
	}

	/* we need this to go all the way to the top of the module
	 * stack, as we need all the extra attributes added (including
	 * complex ones like ntsecuritydescriptor).  We must do this
	 * as system, otherwise a user might end up owning the RID
	 * set, and that would be bad... */
	ret = dsdb_module_add(module, msg,
			      DSDB_FLAG_TOP_MODULE | DSDB_FLAG_AS_SYSTEM
			      | DSDB_MODIFY_RELAX, parent);
	if (ret != LDB_SUCCESS) {
		ldb_asprintf_errstring(ldb, "Failed to add RID Set %s - %s",
				       ldb_dn_get_linearized(msg->dn),
				       ldb_errstring(ldb));
		talloc_free(tmp_ctx);
		return ret;
	}

	/* add the rIDSetReferences link */
	msg = ldb_msg_new(tmp_ctx);
	msg->dn = machine_dn;

	/* we need the extended DN of the RID Set object for
	 * rIDSetReferences */
	ret = dsdb_module_search_dn(module, msg, &res, rid_set_dn, no_attrs,
				    DSDB_FLAG_NEXT_MODULE | DSDB_SEARCH_SHOW_DN_IN_STORAGE_FORMAT, parent);
	if (ret != LDB_SUCCESS) {
		ldb_asprintf_errstring(ldb, "Failed to find extended DN of RID Set %s - %s",
				       ldb_dn_get_linearized(msg->dn),
				       ldb_errstring(ldb));
		talloc_free(tmp_ctx);
		return ret;
	}
	rid_set_dn = res->msgs[0]->dn;


	ret = ldb_msg_add_string(msg, "rIDSetReferences", ldb_dn_get_extended_linearized(msg, rid_set_dn, 1));
	if (ret != LDB_SUCCESS) {
		talloc_free(tmp_ctx);
		return ret;
	}
	msg->elements[0].flags = LDB_FLAG_MOD_ADD;

	ret = dsdb_module_modify(module, msg, DSDB_FLAG_NEXT_MODULE, parent);
	if (ret != LDB_SUCCESS) {
		ldb_asprintf_errstring(ldb, "Failed to add rIDSetReferences to %s - %s",
				       ldb_dn_get_linearized(msg->dn),
				       ldb_errstring(ldb));
		talloc_free(tmp_ctx);
		return ret;
	}

	(*dn) = talloc_steal(mem_ctx, rid_set_dn);

	talloc_free(tmp_ctx);
	return LDB_SUCCESS;
}


/*
  create a RID Set object for this DC
 */
int ridalloc_create_own_rid_set(struct ldb_module *module, TALLOC_CTX *mem_ctx,
				struct ldb_dn **dn, struct ldb_request *parent)
{
	TALLOC_CTX *tmp_ctx = talloc_new(mem_ctx);
	struct ldb_dn *rid_manager_dn, *fsmo_role_dn;
	int ret;
	struct ldb_context *ldb = ldb_module_get_ctx(module);
	struct GUID fsmo_role_guid;
	const struct GUID *our_ntds_guid;
	NTSTATUS status;

	/* work out who is the RID Manager */
	ret = dsdb_module_rid_manager_dn(module, tmp_ctx, &rid_manager_dn, parent);
	if (ret != LDB_SUCCESS) {
		ldb_asprintf_errstring(ldb, "Failed to find RID Manager object - %s",
				       ldb_errstring(ldb));
		talloc_free(tmp_ctx);
		return ret;
	}

	/* find the DN of the RID Manager */
	ret = dsdb_module_reference_dn(module, tmp_ctx, rid_manager_dn, "fSMORoleOwner", &fsmo_role_dn, parent);
	if (ret != LDB_SUCCESS) {
		ldb_asprintf_errstring(ldb, "Failed to find fSMORoleOwner in RID Manager object - %s",
				       ldb_errstring(ldb));
		talloc_free(tmp_ctx);
		return ret;
	}

	status = dsdb_get_extended_dn_guid(fsmo_role_dn, &fsmo_role_guid, "GUID");
	if (!NT_STATUS_IS_OK(status)) {
		talloc_free(tmp_ctx);
		return ldb_operr(ldb_module_get_ctx(module));
	}

	our_ntds_guid = samdb_ntds_objectGUID(ldb_module_get_ctx(module));
	if (!our_ntds_guid) {
		talloc_free(tmp_ctx);
		return ldb_operr(ldb_module_get_ctx(module));
	}

	if (!GUID_equal(&fsmo_role_guid, our_ntds_guid)) {
		ret = ridalloc_poke_rid_manager(module);
		if (ret != LDB_SUCCESS) {
			ldb_asprintf_errstring(ldb,
					"Request for remote creation of "
					"RID Set for this DC failed: %s",
					ldb_errstring(ldb));
		} else {
			ldb_asprintf_errstring(ldb,
					"Remote RID Set creation needed");
		}
		talloc_free(tmp_ctx);
		return LDB_ERR_UNWILLING_TO_PERFORM;
	}

	ret = ridalloc_create_rid_set_ntds(module, mem_ctx, rid_manager_dn, fsmo_role_dn, dn, parent);
	talloc_free(tmp_ctx);
	return ret;
}