Example #1
0
static int extended_dn_read_SID(struct ldb_context *ldb, void *mem_ctx,
			      const struct ldb_val *in, struct ldb_val *out)
{
	struct dom_sid sid;
	enum ndr_err_code ndr_err;
	if (ldif_comparision_objectSid_isString(in)) {
		if (ldif_read_objectSid(ldb, mem_ctx, in, out) == 0) {
			return 0;
		}
	}
	
	/* Perhaps not a string after all */
	*out = data_blob_talloc(mem_ctx, NULL, in->length/2+1);

	if (!out->data) {
		return -1;
	}

	(*out).length = strhex_to_str((char *)out->data, out->length,
				     (const char *)in->data, in->length);

	/* Check it looks like a SID */
	ndr_err = ndr_pull_struct_blob_all(out, mem_ctx, &sid,
					   (ndr_pull_flags_fn_t)ndr_pull_dom_sid);
	if (!NDR_ERR_CODE_IS_SUCCESS(ndr_err)) {
		return -1;
	}
	return 0;
}
static struct share_mode_data *parse_share_modes(TALLOC_CTX *mem_ctx,
						 const TDB_DATA dbuf)
{
	struct share_mode_data *d;
	enum ndr_err_code ndr_err;
	uint32_t i;
	DATA_BLOB blob;

	d = talloc(mem_ctx, struct share_mode_data);
	if (d == NULL) {
		DEBUG(0, ("talloc failed\n"));
		goto fail;
	}

	blob.data = dbuf.dptr;
	blob.length = dbuf.dsize;

	ndr_err = ndr_pull_struct_blob_all(
		&blob, d, d, (ndr_pull_flags_fn_t)ndr_pull_share_mode_data);
	if (!NDR_ERR_CODE_IS_SUCCESS(ndr_err)) {
		DEBUG(1, ("ndr_pull_share_mode_lock failed: %s\n",
			  ndr_errstr(ndr_err)));
		goto fail;
	}

	/*
	 * Initialize the values that are [skip] in the idl. The NDR code does
	 * not initialize them.
	 */

	for (i=0; i<d->num_share_modes; i++) {
		struct share_mode_entry *e = &d->share_modes[i];

		e->stale = false;
		e->lease = NULL;
		if (e->op_type != LEASE_OPLOCK) {
			continue;
		}
		if (e->lease_idx >= d->num_leases) {
			continue;
		}
		e->lease = &d->leases[e->lease_idx];
	}
	d->modified = false;
	d->fresh = false;

	if (DEBUGLEVEL >= 10) {
		DEBUG(10, ("parse_share_modes:\n"));
		NDR_PRINT_DEBUG(share_mode_data, d);
	}

	return d;
fail:
	TALLOC_FREE(d);
	return NULL;
}
Example #3
0
static WERROR dsdb_syntax_DN_BINARY_drsuapi_to_ldb(struct ldb_context *ldb, 
						   const struct dsdb_schema *schema,
						   const struct dsdb_attribute *attr,
						   const struct drsuapi_DsReplicaAttribute *in,
						   TALLOC_CTX *mem_ctx,
						   struct ldb_message_element *out)
{
	uint32_t i;

	out->flags	= 0;
	out->name	= talloc_strdup(mem_ctx, attr->lDAPDisplayName);
	W_ERROR_HAVE_NO_MEMORY(out->name);

	out->num_values	= in->value_ctr.num_values;
	out->values	= talloc_array(mem_ctx, struct ldb_val, out->num_values);
	W_ERROR_HAVE_NO_MEMORY(out->values);

	for (i=0; i < out->num_values; i++) {
		struct drsuapi_DsReplicaObjectIdentifier3Binary id3b;
		char *binary;
		char *str;
		enum ndr_err_code ndr_err;

		if (in->value_ctr.values[i].blob == NULL) {
			return WERR_FOOBAR;
		}

		if (in->value_ctr.values[i].blob->length == 0) {
			return WERR_FOOBAR;
		}

		ndr_err = ndr_pull_struct_blob_all(in->value_ctr.values[i].blob,
						   out->values, schema->iconv_convenience, &id3b,
						   (ndr_pull_flags_fn_t)ndr_pull_drsuapi_DsReplicaObjectIdentifier3Binary);
		if (!NDR_ERR_CODE_IS_SUCCESS(ndr_err)) {
			NTSTATUS status = ndr_map_error2ntstatus(ndr_err);
			return ntstatus_to_werror(status);
		}

		/* TODO: handle id3.guid and id3.sid */
		binary = data_blob_hex_string(out->values, &id3b.binary);
		W_ERROR_HAVE_NO_MEMORY(binary);

		str = talloc_asprintf(out->values, "B:%u:%s:%s",
				      (unsigned int)(id3b.binary.length * 2), /* because of 2 hex chars per byte */
				      binary,
				      id3b.dn);
		W_ERROR_HAVE_NO_MEMORY(str);

		/* TODO: handle id3.guid and id3.sid */
		out->values[i] = data_blob_string_const(str);
	}

	return WERR_OK;
}
Example #4
0
/**
  build a GUID from a NDR data blob
*/
_PUBLIC_ NTSTATUS GUID_from_ndr_blob(const DATA_BLOB *b, struct GUID *guid)
{
	enum ndr_err_code ndr_err;
	TALLOC_CTX *mem_ctx;

	mem_ctx = talloc_new(NULL);
	NT_STATUS_HAVE_NO_MEMORY(mem_ctx);

	ndr_err = ndr_pull_struct_blob_all(b, mem_ctx, NULL, guid,
					   (ndr_pull_flags_fn_t)ndr_pull_GUID);
	talloc_free(mem_ctx);
	return ndr_map_error2ntstatus(ndr_err);
}
Example #5
0
/*
  winreg_CreateKey
*/
static WERROR dcesrv_winreg_CreateKey(struct dcesrv_call_state *dce_call,
				      TALLOC_CTX *mem_ctx,
				      struct winreg_CreateKey *r)
{
	struct dcesrv_handle *h, *newh;
	struct security_descriptor sd;
	struct registry_key *key;
	WERROR result;

	DCESRV_PULL_HANDLE_FAULT(h, r->in.handle, HTYPE_REGKEY);
	key = h->data;

	newh = dcesrv_handle_new(dce_call->context, HTYPE_REGKEY);

	switch (security_session_user_level(dce_call->conn->auth_state.session_info))
	{
	case SECURITY_SYSTEM:
	case SECURITY_ADMINISTRATOR:
		/* the security descriptor is optional */
		if (r->in.secdesc != NULL) {
			DATA_BLOB sdblob;
			enum ndr_err_code ndr_err;
			sdblob.data = r->in.secdesc->sd.data;
			sdblob.length = r->in.secdesc->sd.len;
			if (sdblob.data == NULL) {
				return WERR_INVALID_PARAM;
			}
			ndr_err = ndr_pull_struct_blob_all(&sdblob, mem_ctx, NULL, &sd,
							   (ndr_pull_flags_fn_t)ndr_pull_security_descriptor);
			if (!NDR_ERR_CODE_IS_SUCCESS(ndr_err)) {
				return WERR_INVALID_PARAM;
			}
		}
		
		result = reg_key_add_name(newh, key, r->in.name.name, NULL,
			r->in.secdesc?&sd:NULL, (struct registry_key **)&newh->data);
		if (W_ERROR_IS_OK(result)) {
			r->out.new_handle = &newh->wire_handle;
		} else {
			talloc_free(newh);
		}
		
		return result;
	default:
		return WERR_ACCESS_DENIED;
	}
}
Example #6
0
static WERROR dsdb_syntax_DN_drsuapi_to_ldb(const struct dsdb_schema *schema,
					    const struct dsdb_attribute *attr,
					    const struct drsuapi_DsReplicaAttribute *in,
					    TALLOC_CTX *mem_ctx,
					    struct ldb_message_element *out)
{
	uint32_t i;

	out->flags	= 0;
	out->name	= talloc_strdup(mem_ctx, attr->lDAPDisplayName);
	W_ERROR_HAVE_NO_MEMORY(out->name);

	out->num_values	= in->value_ctr.num_values;
	out->values	= talloc_array(mem_ctx, struct ldb_val, out->num_values);
	W_ERROR_HAVE_NO_MEMORY(out->values);

	for (i=0; i < out->num_values; i++) {
		struct drsuapi_DsReplicaObjectIdentifier3 id3;
		NTSTATUS status;

		if (in->value_ctr.values[i].blob == NULL) {
			return WERR_FOOBAR;
		}

		if (in->value_ctr.values[i].blob->length == 0) {
			return WERR_FOOBAR;
		}

		status = ndr_pull_struct_blob_all(in->value_ctr.values[i].blob,
						  out->values, &id3,
						  (ndr_pull_flags_fn_t)ndr_pull_drsuapi_DsReplicaObjectIdentifier3);
		if (!NT_STATUS_IS_OK(status)) {
			return ntstatus_to_werror(status);
		}

		/* TODO: handle id3.guid and id3.sid */
		out->values[i] = data_blob_string_const(id3.dn);
	}

	return WERR_OK;
}
Example #7
0
/*
  convert a NDR formatted blob to a ldif formatted objectSid
*/
int ldif_write_objectSid(struct ldb_context *ldb, void *mem_ctx,
				const struct ldb_val *in, struct ldb_val *out)
{
	struct dom_sid *sid;
	enum ndr_err_code ndr_err;

	sid = talloc(mem_ctx, struct dom_sid);
	if (sid == NULL) {
		return -1;
	}
	ndr_err = ndr_pull_struct_blob_all(in, sid, sid,
					   (ndr_pull_flags_fn_t)ndr_pull_dom_sid);
	if (!NDR_ERR_CODE_IS_SUCCESS(ndr_err)) {
		talloc_free(sid);
		return -1;
	}
	*out = data_blob_string_const(dom_sid_string(mem_ctx, sid));
	talloc_free(sid);
	if (out->data == NULL) {
		return -1;
	}
	return 0;
}
Example #8
0
static NTSTATUS cmd_eventlog_readlog(struct rpc_pipe_client *cli,
				     TALLOC_CTX *mem_ctx,
				     int argc,
				     const char **argv)
{
	NTSTATUS status = NT_STATUS_OK;
	NTSTATUS result = NT_STATUS_OK;
	struct policy_handle handle;
	struct dcerpc_binding_handle *b = cli->binding_handle;

	uint32_t flags = EVENTLOG_BACKWARDS_READ |
			 EVENTLOG_SEQUENTIAL_READ;
	uint32_t offset = 0;
	uint32_t number_of_bytes = 0;
	uint8_t *data = NULL;
	uint32_t sent_size = 0;
	uint32_t real_size = 0;

	if (argc < 2 || argc > 4) {
		printf("Usage: %s logname [offset] [number_of_bytes]\n", argv[0]);
		return NT_STATUS_OK;
	}

	if (argc >= 3) {
		offset = atoi(argv[2]);
	}

	if (argc >= 4) {
		number_of_bytes = atoi(argv[3]);
		data = talloc_array(mem_ctx, uint8_t, number_of_bytes);
		if (!data) {
			goto done;
		}
	}

	status = get_eventlog_handle(cli, mem_ctx, argv[1], &handle);
	if (!NT_STATUS_IS_OK(status)) {
		return status;
	}

	do {

		enum ndr_err_code ndr_err;
		DATA_BLOB blob;
		struct EVENTLOGRECORD r;
		uint32_t size = 0;
		uint32_t pos = 0;

		status = dcerpc_eventlog_ReadEventLogW(b, mem_ctx,
						       &handle,
						       flags,
						       offset,
						       number_of_bytes,
						       data,
						       &sent_size,
						       &real_size,
						       &result);
		if (!NT_STATUS_IS_OK(status)) {
			return status;
		}
		if (NT_STATUS_EQUAL(result, NT_STATUS_BUFFER_TOO_SMALL) &&
		    real_size > 0 ) {
			number_of_bytes = real_size;
			data = talloc_array(mem_ctx, uint8_t, real_size);
			if (!data) {
				goto done;
			}
			status = dcerpc_eventlog_ReadEventLogW(b, mem_ctx,
							       &handle,
							       flags,
							       offset,
							       number_of_bytes,
							       data,
							       &sent_size,
							       &real_size,
							       &result);
			if (!NT_STATUS_IS_OK(status)) {
				return status;
			}
		}

		if (!NT_STATUS_EQUAL(result, NT_STATUS_END_OF_FILE) &&
		    !NT_STATUS_IS_OK(result)) {
			goto done;
		}

		number_of_bytes = 0;

		size = IVAL(data, pos);

		while (size > 0) {

			blob = data_blob_const(data + pos, size);
			/* dump_data(0, blob.data, blob.length); */
			ndr_err = ndr_pull_struct_blob_all(&blob, mem_ctx, &r,
					   (ndr_pull_flags_fn_t)ndr_pull_EVENTLOGRECORD);
			if (!NDR_ERR_CODE_IS_SUCCESS(ndr_err)) {
				status = ndr_map_error2ntstatus(ndr_err);
				goto done;
			}

			NDR_PRINT_DEBUG(EVENTLOGRECORD, &r);

			pos += size;

			if (pos + 4 > sent_size) {
				break;
			}

			size = IVAL(data, pos);
		}

		offset++;

	} while (NT_STATUS_IS_OK(result));

 done:
	dcerpc_eventlog_CloseEventLog(b, mem_ctx, &handle, &result);

	return status;
}
Example #9
0
/*
  convert a NDR formatted blob to a ldif formatted prefixMap
*/
static int ldif_write_prefixMap(struct ldb_context *ldb, void *mem_ctx,
				const struct ldb_val *in, struct ldb_val *out)
{
	struct prefixMapBlob *blob;
	enum ndr_err_code ndr_err;
	char *string;
	uint32_t i;

	if (ldb_get_flags(ldb) & LDB_FLG_SHOW_BINARY) {
		int err;
		/* try to decode the blob as S4 prefixMap */
		err = ldif_write_NDR(ldb, mem_ctx, in, out,
		                     sizeof(struct prefixMapBlob),
		                     (ndr_pull_flags_fn_t)ndr_pull_prefixMapBlob,
		                     (ndr_print_fn_t)ndr_print_prefixMapBlob,
		                     false);
		if (0 == err) {
			return err;
		}
		/* try parsing it as Windows PrefixMap value */
		return ldif_write_NDR(ldb, mem_ctx, in, out,
		                      sizeof(struct drsuapi_MSPrefixMap_Ctr),
		                      (ndr_pull_flags_fn_t)ndr_pull_drsuapi_MSPrefixMap_Ctr,
		                      (ndr_print_fn_t)ndr_print_drsuapi_MSPrefixMap_Ctr,
		                      true);
	}

	blob = talloc(mem_ctx, struct prefixMapBlob);
	if (blob == NULL) {
		return -1;
	}
	ndr_err = ndr_pull_struct_blob_all(in, blob, 
					   blob,
					   (ndr_pull_flags_fn_t)ndr_pull_prefixMapBlob);
	if (!NDR_ERR_CODE_IS_SUCCESS(ndr_err)) {
		goto failed;
	}
	if (blob->version != PREFIX_MAP_VERSION_DSDB) {
		goto failed;
	}
	string = talloc_strdup(mem_ctx, "");
	if (string == NULL) {
		goto failed;
	}

	for (i=0; i < blob->ctr.dsdb.num_mappings; i++) {
		DATA_BLOB oid_blob;
		char *partial_oid = NULL;

		if (i > 0) {
			string = talloc_asprintf_append(string, ";"); 
		}

		oid_blob = data_blob_const(blob->ctr.dsdb.mappings[i].oid.binary_oid,
					   blob->ctr.dsdb.mappings[i].oid.length);
		if (!ber_read_partial_OID_String(blob, oid_blob, &partial_oid)) {
			DEBUG(0, ("ber_read_partial_OID failed on prefixMap item with id: 0x%X",
				  blob->ctr.dsdb.mappings[i].id_prefix));
			goto failed;
		}
		string = talloc_asprintf_append(string, "%u:%s", 
						   blob->ctr.dsdb.mappings[i].id_prefix,
						   partial_oid);
		talloc_free(discard_const(partial_oid));
		if (string == NULL) {
			goto failed;
		}
	}

	talloc_free(blob);
	*out = data_blob_string_const(string);
	return 0;

failed:
	talloc_free(blob);
	return -1;
}
NTSTATUS leases_db_add(const struct GUID *client_guid,
		       const struct smb2_lease_key *lease_key,
		       const struct file_id *id,
		       const char *servicepath,
		       const char *base_name,
		       const char *stream_name)
{
	TDB_DATA db_key, db_value;
	DATA_BLOB blob;
	struct db_record *rec;
	NTSTATUS status;
	bool ok;
	struct leases_db_value new_value;
	struct leases_db_file new_file;
	struct leases_db_value *value = NULL;
	enum ndr_err_code ndr_err;

	if (!leases_db_init(false)) {
		return NT_STATUS_INTERNAL_ERROR;
	}

	ok = leases_db_key(talloc_tos(), client_guid, lease_key, &db_key);
	if (!ok) {
		DEBUG(10, ("%s: leases_db_key failed\n", __func__));
		return NT_STATUS_NO_MEMORY;
	}

	rec = dbwrap_fetch_locked(leases_db, talloc_tos(), db_key);
	TALLOC_FREE(db_key.dptr);
	if (rec == NULL) {
		return NT_STATUS_INTERNAL_ERROR;
	}

	db_value = dbwrap_record_get_value(rec);
	if (db_value.dsize != 0) {
		uint32_t i;

		DEBUG(10, ("%s: record exists\n", __func__));

		value = talloc(talloc_tos(), struct leases_db_value);
		if (value == NULL) {
			status = NT_STATUS_NO_MEMORY;
			goto out;
		}

		blob.data = db_value.dptr;
		blob.length = db_value.dsize;

		ndr_err = ndr_pull_struct_blob_all(
			&blob, value, value,
			(ndr_pull_flags_fn_t)ndr_pull_leases_db_value);
		if (!NDR_ERR_CODE_IS_SUCCESS(ndr_err)) {
			DEBUG(10, ("%s: ndr_pull_struct_blob_failed: %s\n",
				   __func__, ndr_errstr(ndr_err)));
			status = ndr_map_error2ntstatus(ndr_err);
			goto out;
		}

		/* id must be unique. */
		for (i = 0; i < value->num_files; i++) {
			if (file_id_equal(id, &value->files[i].id)) {
				status = NT_STATUS_OBJECT_NAME_COLLISION;
				goto out;
			}
		}

		value->files = talloc_realloc(value, value->files,
					struct leases_db_file,
					value->num_files + 1);
		if (value->files == NULL) {
			status = NT_STATUS_NO_MEMORY;
			goto out;
		}
		value->files[value->num_files].id = *id;
		value->files[value->num_files].servicepath = servicepath;
		value->files[value->num_files].base_name = base_name;
		value->files[value->num_files].stream_name = stream_name;
		value->num_files += 1;

	} else {
Example #11
0
static WERROR dsdb_syntax_DN_ldb_to_drsuapi(struct ldb_context *ldb, 
					    const struct dsdb_schema *schema,
					    const struct dsdb_attribute *attr,
					    const struct ldb_message_element *in,
					    TALLOC_CTX *mem_ctx,
					    struct drsuapi_DsReplicaAttribute *out)
{
	uint32_t i;
	DATA_BLOB *blobs;

	if (attr->attributeID_id == 0xFFFFFFFF) {
		return WERR_FOOBAR;
	}

	out->attid			= attr->attributeID_id;
	out->value_ctr.num_values	= in->num_values;
	out->value_ctr.values		= talloc_array(mem_ctx,
						       struct drsuapi_DsAttributeValue,
						       in->num_values);
	W_ERROR_HAVE_NO_MEMORY(out->value_ctr.values);

	blobs = talloc_array(mem_ctx, DATA_BLOB, in->num_values);
	W_ERROR_HAVE_NO_MEMORY(blobs);

	for (i=0; i < in->num_values; i++) {
		struct drsuapi_DsReplicaObjectIdentifier3 id3;
		enum ndr_err_code ndr_err;
		const DATA_BLOB *guid_blob, *sid_blob;
		struct ldb_dn *dn;
		TALLOC_CTX *tmp_ctx = talloc_new(mem_ctx);
		W_ERROR_HAVE_NO_MEMORY(tmp_ctx);

		out->value_ctr.values[i].blob	= &blobs[i];

		dn = ldb_dn_from_ldb_val(tmp_ctx, ldb, &in->values[i]);

		W_ERROR_HAVE_NO_MEMORY(dn);

		guid_blob = ldb_dn_get_extended_component(dn, "GUID");

		ZERO_STRUCT(id3);

		if (guid_blob) {
			ndr_err = ndr_pull_struct_blob_all(guid_blob, 
							   tmp_ctx, schema->iconv_convenience, &id3.guid,
							   (ndr_pull_flags_fn_t)ndr_pull_GUID);
			if (!NDR_ERR_CODE_IS_SUCCESS(ndr_err)) {
				NTSTATUS status = ndr_map_error2ntstatus(ndr_err);
				talloc_free(tmp_ctx);
				return ntstatus_to_werror(status);
			}
		}

		sid_blob = ldb_dn_get_extended_component(dn, "SID");
		if (sid_blob) {
			
			ndr_err = ndr_pull_struct_blob_all(sid_blob, 
							   tmp_ctx, schema->iconv_convenience, &id3.sid,
							   (ndr_pull_flags_fn_t)ndr_pull_dom_sid);
			if (!NDR_ERR_CODE_IS_SUCCESS(ndr_err)) {
				NTSTATUS status = ndr_map_error2ntstatus(ndr_err);
				talloc_free(tmp_ctx);
				return ntstatus_to_werror(status);
			}
		}

		id3.dn = ldb_dn_get_linearized(dn);

		ndr_err = ndr_push_struct_blob(&blobs[i], blobs, schema->iconv_convenience, &id3, (ndr_push_flags_fn_t)ndr_push_drsuapi_DsReplicaObjectIdentifier3);
		if (!NDR_ERR_CODE_IS_SUCCESS(ndr_err)) {
			NTSTATUS status = ndr_map_error2ntstatus(ndr_err);
			talloc_free(tmp_ctx);
			return ntstatus_to_werror(status);
		}
		talloc_free(tmp_ctx);
	}

	return WERR_OK;
}
Example #12
0
static WERROR dsdb_syntax_DN_drsuapi_to_ldb(struct ldb_context *ldb, 
					    const struct dsdb_schema *schema,
					    const struct dsdb_attribute *attr,
					    const struct drsuapi_DsReplicaAttribute *in,
					    TALLOC_CTX *mem_ctx,
					    struct ldb_message_element *out)
{
	uint32_t i;
	int ret;

	out->flags	= 0;
	out->name	= talloc_strdup(mem_ctx, attr->lDAPDisplayName);
	W_ERROR_HAVE_NO_MEMORY(out->name);

	out->num_values	= in->value_ctr.num_values;
	out->values	= talloc_array(mem_ctx, struct ldb_val, out->num_values);
	W_ERROR_HAVE_NO_MEMORY(out->values);

	for (i=0; i < out->num_values; i++) {
		struct drsuapi_DsReplicaObjectIdentifier3 id3;
		enum ndr_err_code ndr_err;
		DATA_BLOB guid_blob;
		struct ldb_dn *dn;
		TALLOC_CTX *tmp_ctx = talloc_new(mem_ctx);
		if (!tmp_ctx) {
			W_ERROR_HAVE_NO_MEMORY(tmp_ctx);
		}

		if (in->value_ctr.values[i].blob == NULL) {
			talloc_free(tmp_ctx);
			return WERR_FOOBAR;
		}

		if (in->value_ctr.values[i].blob->length == 0) {
			talloc_free(tmp_ctx);
			return WERR_FOOBAR;
		}

		

		ndr_err = ndr_pull_struct_blob_all(in->value_ctr.values[i].blob,
						   tmp_ctx, schema->iconv_convenience, &id3,
						   (ndr_pull_flags_fn_t)ndr_pull_drsuapi_DsReplicaObjectIdentifier3);
		if (!NDR_ERR_CODE_IS_SUCCESS(ndr_err)) {
			NTSTATUS status = ndr_map_error2ntstatus(ndr_err);
			talloc_free(tmp_ctx);
			return ntstatus_to_werror(status);
		}

		dn = ldb_dn_new(tmp_ctx, ldb, id3.dn);
		if (!dn) {
			talloc_free(tmp_ctx);
			/* If this fails, it must be out of memory, as it does not do much parsing */
			W_ERROR_HAVE_NO_MEMORY(dn);
		}

		ndr_err = ndr_push_struct_blob(&guid_blob, tmp_ctx, schema->iconv_convenience, &id3.guid,
					       (ndr_push_flags_fn_t)ndr_push_GUID);
		if (!NDR_ERR_CODE_IS_SUCCESS(ndr_err)) {
			NTSTATUS status = ndr_map_error2ntstatus(ndr_err);
			talloc_free(tmp_ctx);
			return ntstatus_to_werror(status);
		}

		ret = ldb_dn_set_extended_component(dn, "GUID", &guid_blob);
		if (ret != LDB_SUCCESS) {
			talloc_free(tmp_ctx);
			return WERR_FOOBAR;
		}

		talloc_free(guid_blob.data);

		if (id3.__ndr_size_sid) {
			DATA_BLOB sid_blob;
			ndr_err = ndr_push_struct_blob(&sid_blob, tmp_ctx, schema->iconv_convenience, &id3.sid,
						       (ndr_push_flags_fn_t)ndr_push_dom_sid);
			if (!NDR_ERR_CODE_IS_SUCCESS(ndr_err)) {
				NTSTATUS status = ndr_map_error2ntstatus(ndr_err);
				talloc_free(tmp_ctx);
				return ntstatus_to_werror(status);
			}

			ret = ldb_dn_set_extended_component(dn, "SID", &sid_blob);
			if (ret != LDB_SUCCESS) {
				talloc_free(tmp_ctx);
				return WERR_FOOBAR;
			}
		}

		out->values[i] = data_blob_string_const(ldb_dn_get_extended_linearized(out->values, dn, 1));
		talloc_free(tmp_ctx);
	}

	return WERR_OK;
}
Example #13
0
static  NTSTATUS parse_supplemental_credentials(TALLOC_CTX *mem_ctx,
			const DATA_BLOB *blob,
			struct package_PrimaryKerberosCtr3 **pkb3,
			struct package_PrimaryKerberosCtr4 **pkb4)
{
	NTSTATUS status;
	enum ndr_err_code ndr_err;
	struct supplementalCredentialsBlob scb;
	struct supplementalCredentialsPackage *scpk = NULL;
	DATA_BLOB scpk_blob;
	struct package_PrimaryKerberosBlob *pkb;
	bool newer_keys = false;
	uint32_t j;

	ndr_err = ndr_pull_struct_blob_all(blob, mem_ctx, &scb,
			(ndr_pull_flags_fn_t)ndr_pull_supplementalCredentialsBlob);
	if (!NDR_ERR_CODE_IS_SUCCESS(ndr_err)) {
		status = ndr_map_error2ntstatus(ndr_err);
		goto done;
	}
	if (scb.sub.signature !=
	    SUPPLEMENTAL_CREDENTIALS_SIGNATURE)
	{
		if (DEBUGLEVEL >= 10) {
			NDR_PRINT_DEBUG(supplementalCredentialsBlob, &scb);
		}
		status = NT_STATUS_INVALID_PARAMETER;
		goto done;
	}
	for (j=0; j < scb.sub.num_packages; j++) {
		if (strcmp("Primary:Kerberos-Newer-Keys",
		    scb.sub.packages[j].name) == 0)
		{
			scpk = &scb.sub.packages[j];
			if (!scpk->data || !scpk->data[0]) {
				scpk = NULL;
				continue;
			}
			newer_keys = true;
			break;
		} else  if (strcmp("Primary:Kerberos",
				   scb.sub.packages[j].name) == 0)
		{
			/*
			 * grab this but don't break here:
			 * there might still be newer-keys ...
			 */
			scpk = &scb.sub.packages[j];
			if (!scpk->data || !scpk->data[0]) {
				scpk = NULL;
			}
		}
	}

	if (!scpk) {
		/* no data */
		status = NT_STATUS_OK;
		goto done;
	}

	scpk_blob = strhex_to_data_blob(mem_ctx, scpk->data);
	if (!scpk_blob.data) {
		status = NT_STATUS_NO_MEMORY;
		goto done;
	}

	pkb = talloc_zero(mem_ctx, struct package_PrimaryKerberosBlob);
	if (!pkb) {
		status = NT_STATUS_NO_MEMORY;
		goto done;
	}
	ndr_err = ndr_pull_struct_blob(&scpk_blob, mem_ctx, pkb,
			(ndr_pull_flags_fn_t)ndr_pull_package_PrimaryKerberosBlob);
	if (!NDR_ERR_CODE_IS_SUCCESS(ndr_err)) {
		status = ndr_map_error2ntstatus(ndr_err);
		goto done;
	}

	if (!newer_keys && pkb->version != 3) {
		status = NT_STATUS_INVALID_PARAMETER;
		goto done;
	}

	if (newer_keys && pkb->version != 4) {
		status = NT_STATUS_INVALID_PARAMETER;
		goto done;
	}

	if (pkb->version == 4 && pkb4) {
		*pkb4 = &pkb->ctr.ctr4;
	} else if (pkb->version == 3 && pkb3) {
		*pkb3 = &pkb->ctr.ctr3;
	}

	status = NT_STATUS_OK;

done:
	return status;
}
Example #14
0
static enum ndr_err_code get_blob_sequence_number(DATA_BLOB *blob,
						uint64_t *pseq)
{
	struct ndr_pull ndr = {.data = blob->data, .data_size = blob->length};
	NDR_CHECK(ndr_pull_hyper(&ndr, NDR_SCALARS, pseq));
	return NDR_ERR_SUCCESS;
}

static int share_mode_data_nofree_destructor(struct share_mode_data *d)
{
	return -1;
}

static struct share_mode_data *share_mode_memcache_fetch(TALLOC_CTX *mem_ctx,
					const TDB_DATA id_key,
					DATA_BLOB *blob)
{
	enum ndr_err_code ndr_err;
	struct share_mode_data *d;
	uint64_t sequence_number;
	void *ptr;
	struct file_id id;
	DATA_BLOB key;

	/* Ensure this is a locking_key record. */
	if (id_key.dsize != sizeof(id)) {
		return NULL;
	}

	memcpy(&id, id_key.dptr, id_key.dsize);
	key = memcache_key(&id);

	ptr = memcache_lookup_talloc(NULL,
			SHARE_MODE_LOCK_CACHE,
			key);
	if (ptr == NULL) {
		DEBUG(10,("failed to find entry for key %s\n",
			file_id_string(mem_ctx, &id)));
		return NULL;
	}
	/* sequence number key is at start of blob. */
	ndr_err = get_blob_sequence_number(blob, &sequence_number);
	if (ndr_err != NDR_ERR_SUCCESS) {
		/* Bad blob. Remove entry. */
		DEBUG(10,("bad blob %u key %s\n",
			(unsigned int)ndr_err,
			file_id_string(mem_ctx, &id)));
		memcache_delete(NULL,
			SHARE_MODE_LOCK_CACHE,
			key);
		return NULL;
	}

	d = (struct share_mode_data *)ptr;
	if (d->sequence_number != sequence_number) {
		DEBUG(10,("seq changed (cached 0x%llu) (new 0x%llu) "
			"for key %s\n",
			(unsigned long long)d->sequence_number,
			(unsigned long long)sequence_number,
			file_id_string(mem_ctx, &id)));
		/* Cache out of date. Remove entry. */
		memcache_delete(NULL,
			SHARE_MODE_LOCK_CACHE,
			key);
		return NULL;
	}

	/* Move onto mem_ctx. */
	d = talloc_move(mem_ctx, &ptr);

	/*
	 * Now we own d, prevent the cache from freeing it
	 * when we delete the entry.
	 */
	talloc_set_destructor(d, share_mode_data_nofree_destructor);

	/* Remove from the cache. We own it now. */
	memcache_delete(NULL,
			SHARE_MODE_LOCK_CACHE,
			key);

	/* And reset the destructor to none. */
	talloc_set_destructor(d, NULL);

	DEBUG(10,("fetched entry for file %s seq 0x%llu key %s\n",
		d->base_name,
		(unsigned long long)d->sequence_number,
		file_id_string(mem_ctx, &id)));

	return d;
}

/*******************************************************************
 Get all share mode entries for a dev/inode pair.
********************************************************************/

static struct share_mode_data *parse_share_modes(TALLOC_CTX *mem_ctx,
						const TDB_DATA key,
						const TDB_DATA dbuf)
{
	struct share_mode_data *d;
	enum ndr_err_code ndr_err;
	uint32_t i;
	DATA_BLOB blob;

	blob.data = dbuf.dptr;
	blob.length = dbuf.dsize;

	/* See if we already have a cached copy of this key. */
	d = share_mode_memcache_fetch(mem_ctx, key, &blob);
	if (d != NULL) {
		return d;
	}

	d = talloc(mem_ctx, struct share_mode_data);
	if (d == NULL) {
		DEBUG(0, ("talloc failed\n"));
		goto fail;
	}

	ndr_err = ndr_pull_struct_blob_all(
		&blob, d, d, (ndr_pull_flags_fn_t)ndr_pull_share_mode_data);
	if (!NDR_ERR_CODE_IS_SUCCESS(ndr_err)) {
		DEBUG(1, ("ndr_pull_share_mode_lock failed: %s\n",
			  ndr_errstr(ndr_err)));
		goto fail;
	}

	/*
	 * Initialize the values that are [skip] in the idl. The NDR code does
	 * not initialize them.
	 */

	for (i=0; i<d->num_share_modes; i++) {
		struct share_mode_entry *e = &d->share_modes[i];

		e->stale = false;
		e->lease = NULL;
		if (e->op_type != LEASE_OPLOCK) {
			continue;
		}
		if (e->lease_idx >= d->num_leases) {
			continue;
		}
		e->lease = &d->leases[e->lease_idx];
	}
	d->modified = false;
	d->fresh = false;

	if (DEBUGLEVEL >= 10) {
		DEBUG(10, ("parse_share_modes:\n"));
		NDR_PRINT_DEBUG(share_mode_data, d);
	}

	return d;
fail:
	TALLOC_FREE(d);
	return NULL;
}

/*******************************************************************
 Create a storable data blob from a modified share_mode_data struct.
********************************************************************/

static TDB_DATA unparse_share_modes(struct share_mode_data *d)
{
	DATA_BLOB blob;
	enum ndr_err_code ndr_err;

	if (DEBUGLEVEL >= 10) {
		DEBUG(10, ("unparse_share_modes:\n"));
		NDR_PRINT_DEBUG(share_mode_data, d);
	}

	share_mode_memcache_delete(d);

	/* Update the sequence number. */
	d->sequence_number += 1;

	remove_stale_share_mode_entries(d);

	if (d->num_share_modes == 0) {
		DEBUG(10, ("No used share mode found\n"));
		return make_tdb_data(NULL, 0);
	}

	ndr_err = ndr_push_struct_blob(
		&blob, d, d, (ndr_push_flags_fn_t)ndr_push_share_mode_data);
	if (!NDR_ERR_CODE_IS_SUCCESS(ndr_err)) {
		smb_panic("ndr_push_share_mode_lock failed");
	}

	return make_tdb_data(blob.data, blob.length);
}