Пример #1
0
WERROR rpccli_spoolss_getprinterdata(struct rpc_pipe_client *cli,
				     TALLOC_CTX *mem_ctx,
				     struct policy_handle *handle,
				     const char *value_name,
				     uint32_t offered,
				     enum winreg_Type *type,
				     uint32_t *needed_p,
				     uint8_t **data_p)
{
	NTSTATUS status;
	WERROR werror;
	uint32_t needed;
	uint8_t *data;
	struct dcerpc_binding_handle *b = cli->binding_handle;

	data = talloc_zero_array(mem_ctx, uint8_t, offered);
	W_ERROR_HAVE_NO_MEMORY(data);

	status = dcerpc_spoolss_GetPrinterData(b, mem_ctx,
					       handle,
					       value_name,
					       type,
					       data,
					       offered,
					       &needed,
					       &werror);
	if (!NT_STATUS_IS_OK(status)) {
		return ntstatus_to_werror(status);
	}

	if (W_ERROR_EQUAL(werror, WERR_MORE_DATA)) {
		offered = needed;
		data = talloc_zero_array(mem_ctx, uint8_t, offered);
		W_ERROR_HAVE_NO_MEMORY(data);

		status = dcerpc_spoolss_GetPrinterData(b, mem_ctx,
						       handle,
						       value_name,
						       type,
						       data,
						       offered,
						       &needed,
						       &werror);
	}
	if (!NT_STATUS_IS_OK(status)) {
		return ntstatus_to_werror(status);
	}

	*data_p = data;
	*needed_p = needed;

	return werror;
}
Пример #2
0
static bool test_GetPrinterData(struct torture_context *tctx,
				struct dcerpc_binding_handle *b,
				struct policy_handle *handle,
				const char *value_name,
				WERROR expected_werr,
				uint32_t expected_value)
{
	NTSTATUS status;
	struct spoolss_GetPrinterData gpd;
	uint32_t needed;
	enum winreg_Type type;
	uint8_t *data = talloc_zero_array(tctx, uint8_t, 4);

	torture_comment(tctx, "Testing GetPrinterData(%s).\n", value_name);
	gpd.in.handle = handle;
	gpd.in.value_name = value_name;
	gpd.in.offered = 4;
	gpd.out.needed = &needed;
	gpd.out.type = &type;
	gpd.out.data = data;

	status = dcerpc_spoolss_GetPrinterData_r(b, tctx, &gpd);
	torture_assert_ntstatus_ok(tctx, status, "GetPrinterData failed.");
	torture_assert_werr_equal(tctx, gpd.out.result, expected_werr,
			"GetPrinterData did not return expected error value.");

	if (W_ERROR_IS_OK(expected_werr)) {
		uint32_t value = IVAL(data, 0);
		torture_assert_int_equal(tctx, value,
			expected_value,
			talloc_asprintf(tctx, "GetPrinterData for %s did not return expected value.", value_name));
	}
	return true;
}
Пример #3
0
/** Initialize a way for multiple threads to log to one or more files.
 *
 * @param ctx The talloc context
 * @return the new context, or NULL on error.
 */
fr_logfile_t *fr_logfile_init(TALLOC_CTX *ctx)
{
	fr_logfile_t *lf;

	lf = talloc_zero(ctx, fr_logfile_t);
	if (!lf) return NULL;

	lf->entries = talloc_zero_array(lf, fr_logfile_entry_t, 64);
	if (!lf->entries) {
		talloc_free(lf);
		return NULL;
	}

#ifdef HAVE_PTHREAD_H
	if (pthread_mutex_init(&lf->mutex, NULL) != 0) {
		talloc_free(lf);
		return NULL;
	}
#endif

	lf->max_entries = 64;

	talloc_set_destructor(lf, _logfile_free);

	return lf;
}
Пример #4
0
int daemon_check_srvids(struct ctdb_context *ctdb, TDB_DATA indata,
			TDB_DATA *outdata)
{
	uint64_t *ids;
	int i, num_ids;
	uint8_t *results;

	if ((indata.dsize % sizeof(uint64_t)) != 0) {
		DEBUG(DEBUG_ERR, ("Bad indata in daemon_check_srvids, "
				  "size=%d\n", (int)indata.dsize));
		return -1;
	}

	ids = (uint64_t *)indata.dptr;
	num_ids = indata.dsize / 8;

	results = talloc_zero_array(outdata, uint8_t, (num_ids+7)/8);
	if (results == NULL) {
		DEBUG(DEBUG_ERR, ("talloc failed in daemon_check_srvids\n"));
		return -1;
	}
	for (i=0; i<num_ids; i++) {
		if (srvid_exists(ctdb->srv, ids[i]) == 0) {
			results[i/8] |= (1 << (i%8));
		}
	}
	outdata->dptr = (uint8_t *)results;
	outdata->dsize = talloc_get_size(results);
	return 0;
}
Пример #5
0
/*
 * this is the entry point if SMB2 is selected via
 * the SMB negprot and the given dialect.
 */
static void reply_smb20xx(struct smb_request *req, uint16_t dialect)
{
	uint8_t *smb2_inpdu;
	uint8_t *smb2_hdr;
	uint8_t *smb2_body;
	uint8_t *smb2_dyn;
	size_t len = SMB2_HDR_BODY + 0x24 + 2;

	smb2_inpdu = talloc_zero_array(talloc_tos(), uint8_t, len);
	if (smb2_inpdu == NULL) {
		DEBUG(0, ("Could not push spnego blob\n"));
		reply_nterror(req, NT_STATUS_NO_MEMORY);
		return;
	}
	smb2_hdr = smb2_inpdu;
	smb2_body = smb2_hdr + SMB2_HDR_BODY;
	smb2_dyn = smb2_body + 0x24;

	SIVAL(smb2_hdr, SMB2_HDR_PROTOCOL_ID,	SMB2_MAGIC);
	SIVAL(smb2_hdr, SMB2_HDR_LENGTH,	SMB2_HDR_BODY);

	SSVAL(smb2_body, 0x00, 0x0024);	/* struct size */
	SSVAL(smb2_body, 0x02, 0x0001);	/* dialect count */

	SSVAL(smb2_dyn,  0x00, dialect);

	req->outbuf = NULL;

	smbd_smb2_process_negprot(req->xconn, 0, smb2_inpdu, len);
	return;
}
Пример #6
0
/*
 * this is the entry point if SMB2 is selected via
 * the SMB negprot
 */
void reply_smb2002(struct smb_request *req, uint16_t choice)
{
	uint8_t *smb2_inbuf;
	uint8_t *smb2_hdr;
	uint8_t *smb2_body;
	uint8_t *smb2_dyn;
	size_t len = 4 + SMB2_HDR_BODY + 0x24 + 2;

	smb2_inbuf = talloc_zero_array(talloc_tos(), uint8_t, len);
	if (smb2_inbuf == NULL) {
		DEBUG(0, ("Could not push spnego blob\n"));
		reply_nterror(req, NT_STATUS_NO_MEMORY);
		return;
	}
	smb2_hdr = smb2_inbuf + 4;
	smb2_body = smb2_hdr + SMB2_HDR_BODY;
	smb2_dyn = smb2_body + 0x24;

	SIVAL(smb2_hdr, SMB2_HDR_PROTOCOL_ID,	SMB2_MAGIC);
	SIVAL(smb2_hdr, SMB2_HDR_LENGTH,	SMB2_HDR_BODY);

	SSVAL(smb2_body, 0x00, 0x0024);	/* struct size */
	SSVAL(smb2_body, 0x02, 0x0001);	/* dialect count */

	SSVAL(smb2_dyn,  0x00, 0x0202);	/* dialect 2.002 */

	req->outbuf = NULL;

	smbd_smb2_first_negprot(smbd_server_conn, smb2_inbuf, len);
	return;
}
Пример #7
0
static TID_SRVR_BLK *tr_msg_decode_servers(void * ctx, json_t *jservers, size_t *out_len)
{
  TID_SRVR_BLK *servers = NULL;
  json_t *jsrvr;
  size_t i, num_servers;

  num_servers = json_array_size(jservers);
  tr_debug("tr_msg_decode_servers(): Number of servers = %u.", (unsigned) num_servers);
  
  if (0 == num_servers) {
    tr_debug("tr_msg_decode_servers(): Server array is empty."); 
    return NULL;
  }
  servers = talloc_zero_array(ctx, TID_SRVR_BLK, num_servers);

  for (i = 0; i < num_servers; i++) {
    jsrvr = json_array_get(jservers, i);
    if (0 != tr_msg_decode_one_server(jsrvr, &servers[i])) {
      talloc_free(servers);
      return NULL;
    }


  }
  *out_len = num_servers;
  return servers;
}
Пример #8
0
/** Initialize a way for multiple threads to log to one or more files.
 *
 * @param ctx The talloc context
 * @param max_entries Max file descriptors to cache, and manage locks for.
 * @param max_idle Maximum time a file descriptor can be idle before it's closed.
 * @return the new context, or NULL on error.
 */
exfile_t *exfile_init(TALLOC_CTX *ctx, uint32_t max_entries, uint32_t max_idle)
{
	exfile_t *ef;

	ef = talloc_zero(ctx, exfile_t);
	if (!ef) return NULL;

	ef->entries = talloc_zero_array(ef, exfile_entry_t, max_entries);
	if (!ef->entries) {
		talloc_free(ef);
		return NULL;
	}

#ifdef HAVE_PTHREAD_H
	if (pthread_mutex_init(&ef->mutex, NULL) != 0) {
		talloc_free(ef);
		return NULL;
	}
#endif

	ef->max_entries = max_entries;
	ef->max_idle = max_idle;

	talloc_set_destructor(ef, _exfile_free);

	return ef;
}
Пример #9
0
/*
 *	compose EAP reply packet in EAP-Message attr of RADIUS.  If
 *	EAP exceeds 253, frame it in multiple EAP-Message attrs.
 */
int eap_basic_compose(RADIUS_PACKET *packet, eap_packet_t *reply)
{
	VALUE_PAIR *vp;
	eap_packet_raw_t *eap_packet;
	int rcode;

	if (eap_wireformat(reply) == EAP_INVALID) {
		return RLM_MODULE_INVALID;
	}
	eap_packet = (eap_packet_raw_t *)reply->packet;

	fr_pair_delete_by_num(&(packet->vps), 0, PW_EAP_MESSAGE, TAG_ANY);

	vp = eap_packet2vp(packet, eap_packet);
	if (!vp) return RLM_MODULE_INVALID;
	fr_pair_add(&(packet->vps), vp);

	/*
	 *	EAP-Message is always associated with
	 *	Message-Authenticator but not vice-versa.
	 *
	 *	Don't add a Message-Authenticator if it's already
	 *	there.
	 */
	vp = fr_pair_find_by_num(packet->vps, 0, PW_MESSAGE_AUTHENTICATOR, TAG_ANY);
	if (!vp) {
		vp = fr_pair_afrom_num(packet, 0, PW_MESSAGE_AUTHENTICATOR);
		vp->vp_length = AUTH_VECTOR_LEN;
		vp->vp_octets = talloc_zero_array(vp, uint8_t, vp->vp_length);

		fr_pair_add(&(packet->vps), vp);
	}

	/* Set request reply code, but only if it's not already set. */
	rcode = RLM_MODULE_OK;
	if (!packet->code) switch (reply->code) {
	case PW_EAP_RESPONSE:
	case PW_EAP_SUCCESS:
		packet->code = PW_CODE_ACCESS_ACCEPT;
		rcode = RLM_MODULE_HANDLED;
		break;
	case PW_EAP_FAILURE:
		packet->code = PW_CODE_ACCESS_REJECT;
		rcode = RLM_MODULE_REJECT;
		break;
	case PW_EAP_REQUEST:
		packet->code = PW_CODE_ACCESS_CHALLENGE;
		rcode = RLM_MODULE_HANDLED;
		break;
	default:
		/* Should never enter here */
		ERROR("rlm_eap: reply code %d is unknown, Rejecting the request.", reply->code);
		packet->code = PW_CODE_ACCESS_REJECT;
		break;
	}

	return rcode;
}
Пример #10
0
/*
 *	Convert a buffer to a CSV entry
 */
static rlm_csv_entry_t *file2csv(CONF_SECTION *conf, rlm_csv_t *inst, int lineno, char *buffer)
{
	rlm_csv_entry_t *e;
	int i;
	char *p, *q;

	e = (rlm_csv_entry_t *) talloc_zero_array(inst->tree, uint8_t, sizeof(*e) + inst->used_fields + sizeof(e->data[0]));
	if (!e) {
		cf_log_err_cs(conf, "Out of memory");
		return NULL;
	}

	for (p = buffer, i = 0; p != NULL; p = q, i++) {
		if (!buf2entry(inst, p, &q)) {
			cf_log_err_cs(conf, "Malformed entry in file %s line %d", inst->filename, lineno);
			return NULL;
		}

		if (q) *(q++) = '\0';

		if (i >= inst->num_fields) {
			cf_log_err_cs(conf, "Too many fields at file %s line %d", inst->filename, lineno);
			return NULL;
		}

		/*
		 *	This is the key field.
		 */
		if (i == inst->key_field) {
			e->key = talloc_strdup(e, p);
			continue;
		}

		/*
		 *	This field is unused.  Ignore it.
		 */
		if (inst->field_offsets[i] < 0) continue;

		e->data[inst->field_offsets[i]] = talloc_strdup(e, p);
	}

	if (i < inst->num_fields) {
		cf_log_err_cs(conf, "Too few fields at file %s line %d (%d < %d)", inst->filename, lineno, i, inst->num_fields);
		return NULL;
	}

	/*
	 *	FIXME: Allow duplicate keys later.
	 */
	if (!rbtree_insert(inst->tree, e)) {
		cf_log_err_cs(conf, "Failed inserting entry for filename %s line %d: duplicate entry",
			      inst->filename, lineno);
		return NULL;
	}

	return e;
}
Пример #11
0
/*
  setup a SMB packet at transport level
*/
struct smbcli_request *smbcli_request_setup_transport(struct smbcli_transport *transport,
						      uint8_t command, unsigned int wct, unsigned int buflen)
{
	struct smbcli_request *req;
	size_t size;

	size = NBT_HDR_SIZE + MIN_SMB_SIZE + wct*2 + buflen;

	req = talloc_zero(transport, struct smbcli_request);
	if (!req) {
		return NULL;
	}

	/* setup the request context */
	req->state = SMBCLI_REQUEST_INIT;
	req->transport = transport;
	req->out.size = size;

	/* over allocate by a small amount */
	req->out.allocated = req->out.size + REQ_OVER_ALLOCATION; 

	req->out.buffer = talloc_zero_array(req, uint8_t, req->out.allocated);
	if (!req->out.buffer) {
		return NULL;
	}

	req->out.hdr = req->out.buffer + NBT_HDR_SIZE;
	req->out.vwv = req->out.hdr + HDR_VWV;
	req->out.wct = wct;
	req->out.data = req->out.vwv + VWV(wct) + 2;
	req->out.data_size = buflen;
	req->out.ptr = req->out.data;

	SCVAL(req->out.hdr, HDR_WCT, wct);
	SSVAL(req->out.vwv, VWV(wct), buflen);

	memcpy(req->out.hdr, "\377SMB", 4);
	SCVAL(req->out.hdr,HDR_COM,command);

	SCVAL(req->out.hdr,HDR_FLG, FLAG_CASELESS_PATHNAMES);
	SSVAL(req->out.hdr,HDR_FLG2, 0);

	/* copy the pid, uid and mid to the request */
	SSVAL(req->out.hdr, HDR_PID, 0);
	SSVAL(req->out.hdr, HDR_UID, 0);
	SSVAL(req->out.hdr, HDR_MID, 0);
	SSVAL(req->out.hdr, HDR_TID,0);
	SSVAL(req->out.hdr, HDR_PIDHIGH,0);
	SIVAL(req->out.hdr, HDR_RCLS, 0);
	memset(req->out.hdr+HDR_SS_FIELD, 0, 10);
	
	return req;
}
Пример #12
0
static bool torture_rpc_spoolss_access_printop_setup(struct torture_context *tctx, void **data)
{
    struct torture_access_context *t;

    *data = t = talloc_zero(tctx, struct torture_access_context);

    t->user.num_builtin_memberships = 1;
    t->user.builtin_memberships = talloc_zero_array(t, uint32_t, t->user.num_builtin_memberships);
    t->user.builtin_memberships[0] = BUILTIN_RID_PRINT_OPERATORS;
    t->user.username = talloc_strdup(t, TORTURE_USER_PRINTOPGROUP);
    t->user.admin_rights = true;

    return torture_rpc_spoolss_access_setup_common(tctx, t);
}
Пример #13
0
static bool open_and_sort_dir(vfs_handle_struct *handle,
				struct dirsort_privates *data)
{
	unsigned int i = 0;
	unsigned int total_count = 0;

	data->number_of_entries = 0;

	if (get_sorted_dir_mtime(handle, data, &data->mtime) == false) {
		return false;
	}

	while (SMB_VFS_NEXT_READDIR(handle, data->source_directory, NULL)
	       != NULL) {
		total_count++;
	}

	if (total_count == 0) {
		return false;
	}

	/* Open the underlying directory and count the number of entries
	   Skip back to the beginning as we'll read it again */
	SMB_VFS_NEXT_REWINDDIR(handle, data->source_directory);

	/* Set up an array and read the directory entries into it */
	TALLOC_FREE(data->directory_list); /* destroy previous cache if needed */
	data->directory_list = talloc_zero_array(data,
						 SMB_STRUCT_DIRENT,
						 total_count);
	if (!data->directory_list) {
		return false;
	}
	for (i = 0; i < total_count; i++) {
		SMB_STRUCT_DIRENT *dp = SMB_VFS_NEXT_READDIR(handle,
						data->source_directory,
						NULL);
		if (dp == NULL) {
			break;
		}
		data->directory_list[i] = *dp;
	}

	data->number_of_entries = i;

	/* Sort the directory entries by name */
	TYPESAFE_QSORT(data->directory_list, data->number_of_entries, compare_dirent);
	return true;
}
Пример #14
0
/* setup a trans2 reply, given the data and params sizes */
static NTSTATUS trans2_setup_reply(struct smb_trans2 *trans,
				   uint16_t param_size, uint16_t data_size,
				   uint8_t setup_count)
{
	trans->out.setup_count = setup_count;
	if (setup_count > 0) {
		trans->out.setup = talloc_zero_array(trans, uint16_t, setup_count);
		NT_STATUS_HAVE_NO_MEMORY(trans->out.setup);
	}
	trans->out.params = data_blob_talloc(trans, NULL, param_size);
	if (param_size > 0) NT_STATUS_HAVE_NO_MEMORY(trans->out.params.data);

	trans->out.data = data_blob_talloc(trans, NULL, data_size);
	if (data_size > 0) NT_STATUS_HAVE_NO_MEMORY(trans->out.data.data);

	return NT_STATUS_OK;
}
Пример #15
0
/* setup a nttrans reply, given the data and params sizes */
static NTSTATUS nttrans_setup_reply(struct nttrans_op *op, 
				    struct smb_nttrans *trans,
				    uint32_t param_size, uint32_t data_size,
				    uint8_t setup_count)
{
	trans->out.setup_count = setup_count;
	if (setup_count != 0) {
		trans->out.setup = talloc_zero_array(op, uint8_t, setup_count*2);
		NT_STATUS_HAVE_NO_MEMORY(trans->out.setup);
	}
	trans->out.params = data_blob_talloc(op, NULL, param_size);
	if (param_size != 0) {
		NT_STATUS_HAVE_NO_MEMORY(trans->out.params.data);
	}
	trans->out.data = data_blob_talloc(op, NULL, data_size);
	if (data_size != 0) {
		NT_STATUS_HAVE_NO_MEMORY(trans->out.data.data);
	}
	return NT_STATUS_OK;
}
Пример #16
0
/*
  test surrounding conformant array handling
*/
static bool test_surrounding(struct torture_context *tctx,
						  struct dcerpc_pipe *p)
{
	NTSTATUS status;
	struct echo_TestSurrounding r;

	ZERO_STRUCT(r);
	r.in.data = talloc(tctx, struct echo_Surrounding);

	r.in.data->x = 20;
	r.in.data->surrounding = talloc_zero_array(tctx, uint16_t, r.in.data->x);

	r.out.data = talloc(tctx, struct echo_Surrounding);

	status = dcerpc_echo_TestSurrounding(p, tctx, &r);
	torture_assert_ntstatus_ok(tctx, status, "TestSurrounding failed");
	
	torture_assert(tctx, r.out.data->x == 2 * r.in.data->x,
		"TestSurrounding did not make the array twice as large");

	return true;
}
Пример #17
0
/* Return an array of krb5_enctype values */
static krb5_error_code ms_suptypes_to_ietf_enctypes(TALLOC_CTX *mem_ctx,
						uint32_t enctype_bitmap,
						krb5_enctype **enctypes)
{
	unsigned int i, j = 0;
	*enctypes = talloc_zero_array(mem_ctx, krb5_enctype,
					(8 * sizeof(enctype_bitmap)) + 1);
	if (!*enctypes) {
		return ENOMEM;
	}
	for (i = 0; i < (8 * sizeof(enctype_bitmap)); i++) {
		uint32_t bit_value = (1 << i) & enctype_bitmap;
		if (bit_value & enctype_bitmap) {
			(*enctypes)[j] = ms_suptype_to_ietf_enctype(bit_value);
			if (!(*enctypes)[j]) {
				continue;
			}
			j++;
		}
	}
	(*enctypes)[j] = 0;
	return 0;
}
Пример #18
0
WERROR hexedit_set_buf(struct hexedit *buf, const void *data, size_t sz)
{
	TALLOC_FREE(buf->data);

	buf->data = talloc_zero_array(buf, uint8_t, sz);
	if (buf->data == NULL) {
		return WERR_NOT_ENOUGH_MEMORY;
	}

	if (data != NULL) {
		memcpy(buf->data, data, sz);
	}

	buf->len = sz;
	buf->alloc_size = sz;
	buf->cursor_x = HEX_COL1;
	buf->cursor_y = 0;
	buf->cursor_offset = 0;
	buf->cursor_line_offset = 0;
	buf->nibble = 0;

	return WERR_OK;
}
Пример #19
0
/** Parse module's configuration section and setup destructors
 *
 */
static int module_conf_parse(module_instance_t *node, void **handle)
{
	*handle = NULL;

	/*
	 *	If there is supposed to be instance data, allocate it now.
	 *	Also parse the configuration data, if required.
	 */
	if (node->entry->module->inst_size) {
		/* FIXME: make this rlm_config_t ?? */
		*handle = talloc_zero_array(node, uint8_t, node->entry->module->inst_size);
		rad_assert(handle);

		/*
		 *	So we can see where this configuration is from
		 *	FIXME: set it to rlm_NAME_t, or some such thing
		 */
		talloc_set_name(*handle, "rlm_config_t");

		if (node->entry->module->config &&
		    (cf_section_parse(node->cs, *handle, node->entry->module->config) < 0)) {
			cf_log_err_cs(node->cs,"Invalid configuration for module \"%s\"", node->name);
			talloc_free(*handle);

			return -1;
		}

		/*
		 *	Set the destructor.
		 */
		if (node->entry->module->detach) {
			talloc_set_destructor((void *) *handle, node->entry->module->detach);
		}
	}

	return 0;
}
Пример #20
0
/**
   \details Test dump of a set of recipients

   This function:
   -# builds a recipient list
   -# dumps out the recipient list using mapidump_Recipients()

   \param mt pointer to the top-level mapitest structure

   \return true on success, otherwise false
   
   \note This currently doesn't check the results are sane, so manual inspection is required
*/ 
_PUBLIC_ bool mapitest_mapidump_recipients(struct mapitest *mt)
{
	const char 			**userlist;
	struct SRowSet 			resolved;
	struct PropertyTagArray_r	flaglist;
	struct SPropValue		SPropValue;

	userlist = talloc_array(mt->mem_ctx, const char*, 3);
	userlist[0] = "Mr. Unresolved";
	userlist[1] = "Mr/Ms. Ambiguous";
	userlist[2] = "Mrs. Resolved";

	resolved.cRows = 1;
	resolved.aRow = talloc_array(mt->mem_ctx, struct SRow, resolved.cRows);
	resolved.aRow[0].cValues = 0;
	resolved.aRow[0].lpProps = talloc_zero(mt->mem_ctx, struct SPropValue);
	SPropValue.ulPropTag = PR_OBJECT_TYPE;
	SPropValue.value.l = MAPI_MAILUSER;
	SRow_addprop(&(resolved.aRow[0]), SPropValue);

	SPropValue.ulPropTag = PR_GIVEN_NAME;
	SPropValue.value.lpszA = "gname";
	SRow_addprop(&(resolved.aRow[0]), SPropValue);

	flaglist.cValues = 3;
	flaglist.aulPropTag = talloc_zero_array(mt->mem_ctx, uint32_t, flaglist.cValues);
	flaglist.aulPropTag[0] = MAPI_UNRESOLVED;
	flaglist.aulPropTag[1] = MAPI_AMBIGUOUS;
	flaglist.aulPropTag[2] = MAPI_RESOLVED;
	
	mapidump_Recipients(userlist, &resolved, &flaglist);

	talloc_free(flaglist.aulPropTag);

	return true;
}
/* 
  spoolss_GetPrinterData 
*/
static WERROR dcesrv_spoolss_GetPrinterData(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
		       struct spoolss_GetPrinterData *r)
{
	struct ntptr_GenericHandle *handle;
	struct dcesrv_handle *h;
	WERROR status;

	r->out.type = talloc_zero(mem_ctx, enum winreg_Type);
	W_ERROR_HAVE_NO_MEMORY(r->out.type);

	r->out.needed = talloc_zero(mem_ctx, uint32_t);
	W_ERROR_HAVE_NO_MEMORY(r->out.needed);

	r->out.data = talloc_zero_array(mem_ctx, uint8_t, r->in.offered);
	W_ERROR_HAVE_NO_MEMORY(r->out.data);

	DCESRV_PULL_HANDLE_WERR(h, r->in.handle, DCESRV_HANDLE_ANY);
	handle = talloc_get_type(h->data, struct ntptr_GenericHandle);
	if (!handle)
		return WERR_BADFID;

	switch (handle->type) {
		case NTPTR_HANDLE_SERVER:
			status = ntptr_GetPrintServerData(handle, mem_ctx, r);
			break;
		default:
			status = WERR_FOOBAR;
			break;
	}

	W_ERROR_NOT_OK_RETURN(status);

	*r->out.type	= SPOOLSS_BUFFER_OK(*r->out.type, REG_NONE);
	r->out.data	= SPOOLSS_BUFFER_OK(r->out.data, r->out.data);
	return SPOOLSS_BUFFER_OK(WERR_OK, WERR_MORE_DATA);
}
Пример #22
0
/** Create a new map proc instance
 *
 * This should be called for every map {} section in the configuration.
 *
 * @param ctx to allocate proc instance in.
 * @param proc resolved with #map_proc_find.
 * @param src template.
 * @param maps Head of the list of maps.
 * @return
 *	- New #map_proc_inst_t on success.
 *	- NULL on error.
 */
map_proc_inst_t *map_proc_instantiate(TALLOC_CTX *ctx, map_proc_t const *proc,
				      vp_tmpl_t const *src, vp_map_t const *maps)
{
	map_proc_inst_t *inst;

	inst = talloc_zero(ctx, map_proc_inst_t);
	inst->proc = proc;
	inst->src = src;
	inst->maps = maps;

	if (proc->instantiate) {
		if (proc->inst_size > 0) {
			inst->data = talloc_zero_array(inst, uint8_t, proc->inst_size);
			if (!inst->data) return NULL;
		}

		if (proc->instantiate(inst->data, proc->mod_inst, src, maps) < 0) {
			talloc_free(inst);
			return NULL;
		}
	}

	return inst;
}
Пример #23
0
int
compute_peer_confirm (pwd_session_t *sess, uint8_t *buf, BN_CTX *bnctx)
{
    BIGNUM *x = NULL, *y = NULL;
    HMAC_CTX ctx;
    uint8_t *cruft = NULL;
    int offset, req = -1;

    /*
     * Each component of the cruft will be at most as big as the prime
     */
    if (((cruft = talloc_zero_array(sess, uint8_t, BN_num_bytes(sess->prime))) == NULL) ||
	((x = BN_new()) == NULL) || ((y = BN_new()) == NULL)) {
	DEBUG2("pwd: unable to allocate space to compute confirm!");
	goto fin;
    }

    /*
     * commit is H(k | server_element | server_scalar | peer_element |
     *	       peer_scalar | ciphersuite)
     */
    H_Init(&ctx);

    /*
     * Zero the memory each time because this is mod prime math and some
     * value may start with a few zeros and the previous one did not.
     *
     * First is k
     */
    offset = BN_num_bytes(sess->prime) - BN_num_bytes(sess->k);
    BN_bn2bin(sess->k, cruft + offset);
    H_Update(&ctx, cruft, BN_num_bytes(sess->prime));

    /*
     * then peer element: x, y
     */
    if (!EC_POINT_get_affine_coordinates_GFp(sess->group,
					     sess->peer_element, x, y,
					     bnctx)) {
	DEBUG2("pwd: unable to get coordinates of peer's element");
	goto fin;
    }

    memset(cruft, 0, BN_num_bytes(sess->prime));
    offset = BN_num_bytes(sess->prime) - BN_num_bytes(x);
    BN_bn2bin(x, cruft + offset);
    H_Update(&ctx, cruft, BN_num_bytes(sess->prime));

    memset(cruft, 0, BN_num_bytes(sess->prime));
    offset = BN_num_bytes(sess->prime) - BN_num_bytes(y);
    BN_bn2bin(y, cruft + offset);
    H_Update(&ctx, cruft, BN_num_bytes(sess->prime));

    /*
     * and peer scalar
     */
    memset(cruft, 0, BN_num_bytes(sess->prime));
    offset = BN_num_bytes(sess->order) - BN_num_bytes(sess->peer_scalar);
    BN_bn2bin(sess->peer_scalar, cruft + offset);
    H_Update(&ctx, cruft, BN_num_bytes(sess->order));

    /*
     * then server element: x, y
     */
    if (!EC_POINT_get_affine_coordinates_GFp(sess->group,
					     sess->my_element, x, y,
					     bnctx)) {
	DEBUG2("pwd: unable to get coordinates of server element");
	goto fin;
    }
    memset(cruft, 0, BN_num_bytes(sess->prime));
    offset = BN_num_bytes(sess->prime) - BN_num_bytes(x);
    BN_bn2bin(x, cruft + offset);
    H_Update(&ctx, cruft, BN_num_bytes(sess->prime));

    memset(cruft, 0, BN_num_bytes(sess->prime));
    offset = BN_num_bytes(sess->prime) - BN_num_bytes(y);
    BN_bn2bin(y, cruft + offset);
    H_Update(&ctx, cruft, BN_num_bytes(sess->prime));

    /*
     * and server scalar
     */
    memset(cruft, 0, BN_num_bytes(sess->prime));
    offset = BN_num_bytes(sess->order) - BN_num_bytes(sess->my_scalar);
    BN_bn2bin(sess->my_scalar, cruft + offset);
    H_Update(&ctx, cruft, BN_num_bytes(sess->order));

    /*
     * finally, ciphersuite
     */
    H_Update(&ctx, (uint8_t *)&sess->ciphersuite, sizeof(sess->ciphersuite));

    H_Final(&ctx, buf);

    req = 0;
fin:
    if (cruft != NULL) {
	    talloc_free(cruft);
    }
    BN_free(x);
    BN_free(y);

    return req;
}
Пример #24
0
int
compute_password_element (pwd_session_t *sess, uint16_t grp_num,
			  char *password, int password_len,
			  char *id_server, int id_server_len,
			  char *id_peer, int id_peer_len,
			  uint32_t *token)
{
    BIGNUM *x_candidate = NULL, *rnd = NULL, *cofactor = NULL;
    HMAC_CTX ctx;
    uint8_t pwe_digest[SHA256_DIGEST_LENGTH], *prfbuf = NULL, ctr;
    int nid, is_odd, primebitlen, primebytelen, ret = 0;

    switch (grp_num) { /* from IANA registry for IKE D-H groups */
	case 19:
	    nid = NID_X9_62_prime256v1;
	    break;
	case 20:
	    nid = NID_secp384r1;
	    break;
	case 21:
	    nid = NID_secp521r1;
	    break;
	case 25:
	    nid = NID_X9_62_prime192v1;
	    break;
	case 26:
	    nid = NID_secp224r1;
	    break;
	default:
	    DEBUG("unknown group %d", grp_num);
	    goto fail;
    }

    sess->pwe = NULL;
    sess->order = NULL;
    sess->prime = NULL;

    if ((sess->group = EC_GROUP_new_by_curve_name(nid)) == NULL) {
	DEBUG("unable to create EC_GROUP");
	goto fail;
    }

    if (((rnd = BN_new()) == NULL) ||
	((cofactor = BN_new()) == NULL) ||
	((sess->pwe = EC_POINT_new(sess->group)) == NULL) ||
	((sess->order = BN_new()) == NULL) ||
	((sess->prime = BN_new()) == NULL) ||
	((x_candidate = BN_new()) == NULL)) {
	DEBUG("unable to create bignums");
	goto fail;
    }

    if (!EC_GROUP_get_curve_GFp(sess->group, sess->prime, NULL, NULL, NULL))
    {
	DEBUG("unable to get prime for GFp curve");
	goto fail;
    }
    if (!EC_GROUP_get_order(sess->group, sess->order, NULL)) {
	DEBUG("unable to get order for curve");
	goto fail;
    }
    if (!EC_GROUP_get_cofactor(sess->group, cofactor, NULL)) {
	DEBUG("unable to get cofactor for curve");
	goto fail;
    }
    primebitlen = BN_num_bits(sess->prime);
    primebytelen = BN_num_bytes(sess->prime);
    if ((prfbuf = talloc_zero_array(sess, uint8_t, primebytelen)) == NULL) {
	DEBUG("unable to alloc space for prf buffer");
	goto fail;
    }
    ctr = 0;
    while (1) {
	if (ctr > 10) {
	    DEBUG("unable to find random point on curve for group %d, something's fishy", grp_num);
	    goto fail;
	}
	ctr++;

	/*
	 * compute counter-mode password value and stretch to prime
	 *    pwd-seed = H(token | peer-id | server-id | password |
	 *		   counter)
	 */
	H_Init(&ctx);
	H_Update(&ctx, (uint8_t *)token, sizeof(*token));
	H_Update(&ctx, (uint8_t *)id_peer, id_peer_len);
	H_Update(&ctx, (uint8_t *)id_server, id_server_len);
	H_Update(&ctx, (uint8_t *)password, password_len);
	H_Update(&ctx, (uint8_t *)&ctr, sizeof(ctr));
	H_Final(&ctx, pwe_digest);

	BN_bin2bn(pwe_digest, SHA256_DIGEST_LENGTH, rnd);
	eap_pwd_kdf(pwe_digest, SHA256_DIGEST_LENGTH,
		    "EAP-pwd Hunting And Pecking",
		    strlen("EAP-pwd Hunting And Pecking"),
		    prfbuf, primebitlen);

	BN_bin2bn(prfbuf, primebytelen, x_candidate);
	/*
	 * eap_pwd_kdf() returns a string of bits 0..primebitlen but
	 * BN_bin2bn will treat that string of bits as a big endian
	 * number. If the primebitlen is not an even multiple of 8
	 * then excessive bits-- those _after_ primebitlen-- so now
	 * we have to shift right the amount we masked off.
	 */
	if (primebitlen % 8) {
	    BN_rshift(x_candidate, x_candidate, (8 - (primebitlen % 8)));
	}
	if (BN_ucmp(x_candidate, sess->prime) >= 0) {
	    continue;
	}
	/*
	 * need to unambiguously identify the solution, if there is
	 * one...
	 */
	if (BN_is_odd(rnd)) {
	    is_odd = 1;
	} else {
	    is_odd = 0;
	}
	/*
	 * solve the quadratic equation, if it's not solvable then we
	 * don't have a point
	 */
	if (!EC_POINT_set_compressed_coordinates_GFp(sess->group,
						     sess->pwe,
						     x_candidate,
						     is_odd, NULL)) {
	    continue;
	}
	/*
	 * If there's a solution to the equation then the point must be
	 * on the curve so why check again explicitly? OpenSSL code
	 * says this is required by X9.62. We're not X9.62 but it can't
	 * hurt just to be sure.
	 */
	if (!EC_POINT_is_on_curve(sess->group, sess->pwe, NULL)) {
	    DEBUG("EAP-pwd: point is not on curve");
	    continue;
	}

	if (BN_cmp(cofactor, BN_value_one())) {
	    /* make sure the point is not in a small sub-group */
	    if (!EC_POINT_mul(sess->group, sess->pwe, NULL, sess->pwe,
			      cofactor, NULL)) {
		DEBUG("EAP-pwd: cannot multiply generator by order");
		continue;
	    }
	    if (EC_POINT_is_at_infinity(sess->group, sess->pwe)) {
		DEBUG("EAP-pwd: point is at infinity");
		continue;
	    }
	}
	/* if we got here then we have a new generator. */
	break;
    }
    sess->group_num = grp_num;
    if (0) {
fail:				/* DON'T free sess, it's in handler->opaque */
	ret = -1;
    }
    /* cleanliness and order.... */
    BN_free(cofactor);
    BN_free(x_candidate);
    BN_free(rnd);
    talloc_free(prfbuf);

    return ret;
}
Пример #25
0
// target must be initialized to zero
static void ebml_parse_element(struct ebml_parse_ctx *ctx, void *target,
                               uint8_t *data, int size,
                               const struct ebml_elem_desc *type, int level)
{
    assert(type->type == EBML_TYPE_SUBELEMENTS);
    assert(level < 8);
    MP_DBG(ctx, "%.*sParsing element %s\n", level, "       ", type->name);

    char *s = target;
    uint8_t *end = data + size;
    uint8_t *p = data;
    int num_elems[MAX_EBML_SUBELEMENTS] = {0};
    while (p < end) {
        uint8_t *startp = p;
        int len;
        uint32_t id = ebml_parse_id(p, end - p, &len);
        if (len > end - p)
            goto past_end_error;
        if (len < 0) {
            MP_DBG(ctx, "Error parsing subelement id\n");
            goto other_error;
        }
        p += len;
        uint64_t length = ebml_parse_length(p, end - p, &len);
        if (len > end - p)
            goto past_end_error;
        if (len < 0) {
            MP_DBG(ctx, "Error parsing subelement length\n");
            goto other_error;
        }
        p += len;

        int field_idx = -1;
        for (int i = 0; i < type->field_count; i++)
            if (type->fields[i].id == id) {
                field_idx = i;
                num_elems[i]++;
                if (num_elems[i] >= 0x70000000) {
                    MP_ERR(ctx, "Too many EBML subelements.\n");
                    goto other_error;
                }
                break;
            }

        if (length > end - p) {
            if (field_idx >= 0 && type->fields[field_idx].desc->type
                != EBML_TYPE_SUBELEMENTS) {
                MP_DBG(ctx, "Subelement content goes "
                       "past end of containing element\n");
                goto other_error;
            }
            // Try to parse what is possible from inside this partial element
            ctx->has_errors = true;
            length = end - p;
        }
        p += length;

        continue;

    past_end_error:
        MP_DBG(ctx, "Subelement headers go past end of containing element\n");
    other_error:
        ctx->has_errors = true;
        end = startp;
        break;
    }

    for (int i = 0; i < type->field_count; i++)
        if (num_elems[i] && type->fields[i].multiple) {
            char *ptr = s + type->fields[i].offset;
            switch (type->fields[i].desc->type) {
            case EBML_TYPE_SUBELEMENTS: {
                size_t max = 1000000000 / type->fields[i].desc->size;
                if (num_elems[i] > max) {
                    MP_ERR(ctx, "Too many subelements.\n");
                    num_elems[i] = max;
                }
                int sz = num_elems[i] * type->fields[i].desc->size;
                *(generic_struct **) ptr = talloc_zero_size(ctx->talloc_ctx, sz);
                break;
            }
            case EBML_TYPE_UINT:
                *(uint64_t **) ptr = talloc_zero_array(ctx->talloc_ctx,
                                                       uint64_t, num_elems[i]);
                break;
            case EBML_TYPE_SINT:
                *(int64_t **) ptr = talloc_zero_array(ctx->talloc_ctx,
                                                      int64_t, num_elems[i]);
                break;
            case EBML_TYPE_FLOAT:
                *(double **) ptr = talloc_zero_array(ctx->talloc_ctx,
                                                     double, num_elems[i]);
                break;
            case EBML_TYPE_STR:
            case EBML_TYPE_BINARY:
                *(struct bstr **) ptr = talloc_zero_array(ctx->talloc_ctx,
                                                          struct bstr,
                                                          num_elems[i]);
                break;
            case EBML_TYPE_EBML_ID:
                *(int32_t **) ptr = talloc_zero_array(ctx->talloc_ctx,
                                                      uint32_t, num_elems[i]);
                break;
            default:
                abort();
            }
        }
Пример #26
0
static REQUEST *request_setup(FILE *fp)
{
	VALUE_PAIR *vp;
	REQUEST *request;
	vp_cursor_t cursor;

	/*
	 *	Create and initialize the new request.
	 */
	request = request_alloc(NULL);

	request->packet = rad_alloc(request, false);
	if (!request->packet) {
		ERROR("No memory");
		talloc_free(request);
		return NULL;
	}

	request->reply = rad_alloc(request, false);
	if (!request->reply) {
		ERROR("No memory");
		talloc_free(request);
		return NULL;
	}

	request->listener = listen_alloc(request);
	request->client = client_alloc(request);

	request->number = 0;

	request->master_state = REQUEST_ACTIVE;
	request->child_state = REQUEST_RUNNING;
	request->handle = NULL;
	request->server = talloc_typed_strdup(request, "default");

	request->root = &main_config;

	/*
	 *	Read packet from fp
	 */
	if (readvp2(request->packet, &request->packet->vps, fp, &filedone) < 0) {
		fr_perror("unittest");
		talloc_free(request);
		return NULL;
	}

	/*
	 *	Set the defaults for IPs, etc.
	 */
	request->packet->code = PW_CODE_ACCESS_REQUEST;

	request->packet->src_ipaddr.af = AF_INET;
	request->packet->src_ipaddr.ipaddr.ip4addr.s_addr = htonl(INADDR_LOOPBACK);
	request->packet->src_port = 18120;

	request->packet->dst_ipaddr.af = AF_INET;
	request->packet->dst_ipaddr.ipaddr.ip4addr.s_addr = htonl(INADDR_LOOPBACK);
	request->packet->dst_port = 1812;

	/*
	 *	Copied from radclient
	 */
#if 1
	/*
	 *	Fix up Digest-Attributes issues
	 */
	for (vp = fr_cursor_init(&cursor, &request->packet->vps);
	     vp;
	     vp = fr_cursor_next(&cursor)) {
		/*
		 *	Double quoted strings get marked up as xlat expansions,
		 *	but we don't support that here.
		 */
		if (vp->type == VT_XLAT) {
			vp->vp_strvalue = vp->value.xlat;
			vp->value.xlat = NULL;
			vp->type = VT_DATA;
		}

		if (!vp->da->vendor) switch (vp->da->attr) {
		default:
			break;

			/*
			 *	Allow it to set the packet type in
			 *	the attributes read from the file.
			 */
		case PW_PACKET_TYPE:
			request->packet->code = vp->vp_integer;
			break;

		case PW_PACKET_DST_PORT:
			request->packet->dst_port = (vp->vp_integer & 0xffff);
			break;

		case PW_PACKET_DST_IP_ADDRESS:
			request->packet->dst_ipaddr.af = AF_INET;
			request->packet->dst_ipaddr.ipaddr.ip4addr.s_addr = vp->vp_ipaddr;
			break;

		case PW_PACKET_DST_IPV6_ADDRESS:
			request->packet->dst_ipaddr.af = AF_INET6;
			request->packet->dst_ipaddr.ipaddr.ip6addr = vp->vp_ipv6addr;
			break;

		case PW_PACKET_SRC_PORT:
			request->packet->src_port = (vp->vp_integer & 0xffff);
			break;

		case PW_PACKET_SRC_IP_ADDRESS:
			request->packet->src_ipaddr.af = AF_INET;
			request->packet->src_ipaddr.ipaddr.ip4addr.s_addr = vp->vp_ipaddr;
			break;

		case PW_PACKET_SRC_IPV6_ADDRESS:
			request->packet->src_ipaddr.af = AF_INET6;
			request->packet->src_ipaddr.ipaddr.ip6addr = vp->vp_ipv6addr;
			break;

		case PW_CHAP_PASSWORD: {
			int i, already_hex = 0;

			/*
			 *	If it's 17 octets, it *might* be already encoded.
			 *	Or, it might just be a 17-character password (maybe UTF-8)
			 *	Check it for non-printable characters.  The odds of ALL
			 *	of the characters being 32..255 is (1-7/8)^17, or (1/8)^17,
			 *	or 1/(2^51), which is pretty much zero.
			 */
			if (vp->length == 17) {
				for (i = 0; i < 17; i++) {
					if (vp->vp_octets[i] < 32) {
						already_hex = 1;
						break;
					}
				}
			}

			/*
			 *	Allow the user to specify ASCII or hex CHAP-Password
			 */
			if (!already_hex) {
				uint8_t *p;
				size_t len, len2;

				len = len2 = vp->length;
				if (len2 < 17) len2 = 17;

				p = talloc_zero_array(vp, uint8_t, len2);

				memcpy(p, vp->vp_strvalue, len);

				rad_chap_encode(request->packet,
						p,
						fr_rand() & 0xff, vp);
				vp->vp_octets = p;
				vp->length = 17;
			}
		}
			break;

		case PW_DIGEST_REALM:
		case PW_DIGEST_NONCE:
		case PW_DIGEST_METHOD:
		case PW_DIGEST_URI:
		case PW_DIGEST_QOP:
		case PW_DIGEST_ALGORITHM:
		case PW_DIGEST_BODY_DIGEST:
		case PW_DIGEST_CNONCE:
		case PW_DIGEST_NONCE_COUNT:
		case PW_DIGEST_USER_NAME:
			/* overlapping! */
		{
			DICT_ATTR const *da;
			uint8_t *p, *q;

			p = talloc_array(vp, uint8_t, vp->length + 2);

			memcpy(p + 2, vp->vp_octets, vp->length);
			p[0] = vp->da->attr - PW_DIGEST_REALM + 1;
			vp->length += 2;
			p[1] = vp->length;

			da = dict_attrbyvalue(PW_DIGEST_ATTRIBUTES, 0);
			rad_assert(da != NULL);
			vp->da = da;

			/*
			 *	Re-do pairmemsteal ourselves,
			 *	because we play games with
			 *	vp->da, and pairmemsteal goes
			 *	to GREAT lengths to sanitize
			 *	and fix and change and
			 *	double-check the various
			 *	fields.
			 */
			memcpy(&q, &vp->vp_octets, sizeof(q));
			talloc_free(q);

			vp->vp_octets = talloc_steal(vp, p);
			vp->type = VT_DATA;

			VERIFY_VP(vp);
		}

		break;
		}
	} /* loop over the VP's we read in */
#endif

	if (debug_flag) {
		for (vp = fr_cursor_init(&cursor, &request->packet->vps);
		     vp;
		     vp = fr_cursor_next(&cursor)) {
			/*
			 *	Take this opportunity to verify all the VALUE_PAIRs are still valid.
			 */
			if (!talloc_get_type(vp, VALUE_PAIR)) {
				ERROR("Expected VALUE_PAIR pointer got \"%s\"", talloc_get_name(vp));

				fr_log_talloc_report(vp);
				rad_assert(0);
			}

			vp_print(fr_log_fp, vp);
		}
		fflush(fr_log_fp);
	}

	/*
	 *	FIXME: set IPs, etc.
	 */
	request->packet->code = PW_CODE_ACCESS_REQUEST;

	request->packet->src_ipaddr.af = AF_INET;
	request->packet->src_ipaddr.ipaddr.ip4addr.s_addr = htonl(INADDR_LOOPBACK);
	request->packet->src_port = 18120;

	request->packet->dst_ipaddr.af = AF_INET;
	request->packet->dst_ipaddr.ipaddr.ip4addr.s_addr = htonl(INADDR_LOOPBACK);
	request->packet->dst_port = 1812;

	/*
	 *	Build the reply template from the request.
	 */
	request->reply->sockfd = request->packet->sockfd;
	request->reply->dst_ipaddr = request->packet->src_ipaddr;
	request->reply->src_ipaddr = request->packet->dst_ipaddr;
	request->reply->dst_port = request->packet->src_port;
	request->reply->src_port = request->packet->dst_port;
	request->reply->id = request->packet->id;
	request->reply->code = 0; /* UNKNOWN code */
	memcpy(request->reply->vector, request->packet->vector,
	       sizeof(request->reply->vector));
	request->reply->vps = NULL;
	request->reply->data = NULL;
	request->reply->data_len = 0;

	/*
	 *	Debugging
	 */
	request->log.lvl = debug_flag;
	request->log.func = vradlog_request;

	request->username = pairfind(request->packet->vps, PW_USER_NAME, 0, TAG_ANY);
	request->password = pairfind(request->packet->vps, PW_USER_PASSWORD, 0, TAG_ANY);

	return request;
}
Пример #27
0
static void store_records(struct ctdb_context *ctdb, struct event_context *ev)
{
    TDB_DATA key, data;
    struct ctdb_db_context *ctdb_db;
    TALLOC_CTX *tmp_ctx = talloc_new(ctdb);
    int ret;
    struct ctdb_record_handle *h;
    uint32_t i=0;

    ctdb_db = ctdb_db_handle(ctdb, "test.tdb");

    srandom(time(NULL) ^ getpid());

    start_timer();

    printf("working with %d records\n", num_records);
    while (1) {
        unsigned r = random() % num_records;
        key.dptr = (uint8_t *)&r;
        key.dsize = sizeof(r);

        h = ctdb_fetch_lock(ctdb_db, tmp_ctx, key, &data);
        if (h == NULL) {
            printf("Failed to fetch record '%s' on node %d\n",
                   (const char *)key.dptr, ctdb_get_pnn(ctdb));
            talloc_free(tmp_ctx);
            return;
        }

        if (random() % 100 < delete_pct) {
            data.dptr = NULL;
            data.dsize = 0;
        } else {
            data.dptr = talloc_zero_size(h, data.dsize + sizeof(r));
            data.dsize += sizeof(r);
        }

        ret = ctdb_record_store(h, data);
        if (ret != 0) {
            printf("Failed to store record\n");
        }

        if (data.dptr == NULL && data.dsize == 0) {
            struct ctdb_control_schedule_for_deletion *dd;
            TDB_DATA indata;
            int32_t status;

            indata.dsize = offsetof(struct ctdb_control_schedule_for_deletion, key) + key.dsize;
            indata.dptr = talloc_zero_array(ctdb, uint8_t, indata.dsize);
            if (indata.dptr == NULL) {
                printf("out of memory\n");
                exit(1);
            }
            dd = (struct ctdb_control_schedule_for_deletion *)(void *)indata.dptr;
            dd->db_id = ctdb_db->db_id;
            dd->hdr = *ctdb_header_from_record_handle(h);
            dd->keylen = key.dsize;
            memcpy(dd->key, key.dptr, key.dsize);

            ret = ctdb_control(ctdb,
                               CTDB_CURRENT_NODE,
                               ctdb_db->db_id,
                               CTDB_CONTROL_SCHEDULE_FOR_DELETION,
                               0, /* flags */
                               indata,
                               NULL, /* mem_ctx */
                               NULL, /* outdata */
                               &status,
                               NULL, /* timeout : NULL == wait forever */
                               NULL); /* error message */

            talloc_free(indata.dptr);

            if (ret != 0 || status != 0) {
                DEBUG(DEBUG_ERR, (__location__ " Error sending "
                                  "SCHEDULE_FOR_DELETION "
                                  "control.\n"));
            }
        }

        talloc_free(h);

        if (i % 1000 == 0) {
            printf("%7.0f recs/second   %u total\r", 1000.0 / end_timer(), i);
            fflush(stdout);
            start_timer();
        }
        i++;
    }

    talloc_free(tmp_ctx);
}
Пример #28
0
/*
  setup a chained reply in req->out with the given word count and
  initial data buffer size.
*/
NTSTATUS smbcli_chained_request_setup(struct smbcli_request *req,
				      uint8_t command, 
				      unsigned int wct, size_t buflen)
{
	size_t wct_ofs;
	size_t size;

	/*
	 * here we only support one chained command
	 * If someone needs longer chains, the low
	 * level code should be used directly.
	 */
	if (req->subreqs[0] != NULL) {
		return NT_STATUS_INVALID_PARAMETER_MIX;
	}
	if (req->subreqs[1] != NULL) {
		return NT_STATUS_INVALID_PARAMETER_MIX;
	}

	req->subreqs[0] = smbcli_transport_setup_subreq(req);
	if (req->subreqs[0] == NULL) {
		return NT_STATUS_NO_MEMORY;
	}

	wct_ofs = smb1cli_req_wct_ofs(req->subreqs, 1);

	size = NBT_HDR_SIZE + wct_ofs + 1 + VWV(wct) + 2 + buflen;

	req->out.size = size;

	/* over allocate by a small amount */
	req->out.allocated = req->out.size + REQ_OVER_ALLOCATION;

	req->out.buffer = talloc_zero_array(req, uint8_t, req->out.allocated);
	if (!req->out.buffer) {
		return NT_STATUS_NO_MEMORY;
	}

	req->out.hdr = req->out.buffer + NBT_HDR_SIZE;
	req->out.vwv = req->out.hdr + wct_ofs;
	req->out.wct = wct;
	req->out.data = req->out.vwv + VWV(wct) + 2;
	req->out.data_size = buflen;
	req->out.ptr = req->out.data;

	SCVAL(req->out.hdr, HDR_WCT, wct);
	SSVAL(req->out.vwv, VWV(wct), buflen);

	memcpy(req->out.hdr, "\377SMB", 4);
	SCVAL(req->out.hdr,HDR_COM,command);

	SCVAL(req->out.hdr,HDR_FLG, FLAG_CASELESS_PATHNAMES);
	SSVAL(req->out.hdr,HDR_FLG2, 0);

	/* copy the pid, uid and mid to the request */
	SSVAL(req->out.hdr, HDR_PID, 0);
	SSVAL(req->out.hdr, HDR_UID, 0);
	SSVAL(req->out.hdr, HDR_MID, 0);
	SSVAL(req->out.hdr, HDR_TID,0);
	SSVAL(req->out.hdr, HDR_PIDHIGH,0);
	SIVAL(req->out.hdr, HDR_RCLS, 0);
	memset(req->out.hdr+HDR_SS_FIELD, 0, 10);

	if (req->session != NULL) {
		SSVAL(req->out.hdr, HDR_FLG2, req->session->flags2);
		SSVAL(req->out.hdr, HDR_PID, req->session->pid & 0xFFFF);
		SSVAL(req->out.hdr, HDR_PIDHIGH, req->session->pid >> 16);
		SSVAL(req->out.hdr, HDR_UID, req->session->vuid);
	}
Пример #29
0
static int
mod_authenticate (void *arg, eap_handler_t *handler)
{
    pwd_session_t *pwd_session;
    pwd_hdr *hdr;
    pwd_id_packet *id;
    eap_packet_t *response;
    REQUEST *request, *fake;
    VALUE_PAIR *pw, *vp;
    EAP_DS *eap_ds;
    int len, ret = 0;
    eap_pwd_t *inst = (eap_pwd_t *)arg;
    uint16_t offset;
    uint8_t exch, *buf, *ptr, msk[MSK_EMSK_LEN], emsk[MSK_EMSK_LEN];
    uint8_t peer_confirm[SHA256_DIGEST_LENGTH];
    BIGNUM *x = NULL, *y = NULL;

    if ((!handler) ||
	((eap_ds = handler->eap_ds) == NULL) ||
	(!inst)) {
	return 0;
    }
    pwd_session = (pwd_session_t *)handler->opaque;
    request = handler->request;
    response = handler->eap_ds->response;
    hdr = (pwd_hdr *)response->type.data;

    buf = hdr->data;
    len = response->type.length - sizeof(pwd_hdr);

    /*
     * see if we're fragmenting, if so continue until we're done
     */
    if (pwd_session->out_buf_pos) {
	if (len) {
	    RDEBUG2("pwd got something more than an ACK for a fragment");
	}
	return send_pwd_request(pwd_session, eap_ds);
    }

    /*
     * the first fragment will have a total length, make a
     * buffer to hold all the fragments
     */
    if (EAP_PWD_GET_LENGTH_BIT(hdr)) {
	if (pwd_session->in_buf) {
	    RDEBUG2("pwd already alloced buffer for fragments");
	    return 0;
	}
	pwd_session->in_buf_len = ntohs(buf[0] * 256 | buf[1]);
	if ((pwd_session->in_buf = talloc_zero_array(pwd_session, uint8_t,
						     pwd_session->in_buf_len)) == NULL) {
	    RDEBUG2("pwd cannot allocate %d buffer to hold fragments",
		    pwd_session->in_buf_len);
	    return 0;
	}
	memset(pwd_session->in_buf, 0, pwd_session->in_buf_len);
	pwd_session->in_buf_pos = 0;
	buf += sizeof(uint16_t);
	len -= sizeof(uint16_t);
    }

    /*
     * all fragments, including the 1st will have the M(ore) bit set,
     * buffer those fragments!
     */
    if (EAP_PWD_GET_MORE_BIT(hdr)) {
	rad_assert(pwd_session->in_buf != NULL);
	if ((pwd_session->in_buf_pos + len) > pwd_session->in_buf_len) {
	    RDEBUG2("pwd will not overflow a fragment buffer. Nope, not prudent.");
	    return 0;
	}
	memcpy(pwd_session->in_buf + pwd_session->in_buf_pos, buf, len);
	pwd_session->in_buf_pos += len;

	/*
	 * send back an ACK for this fragment
	 */
	exch = EAP_PWD_GET_EXCHANGE(hdr);
	eap_ds->request->code = PW_EAP_REQUEST;
	eap_ds->request->type.num = PW_EAP_PWD;
	eap_ds->request->type.length = sizeof(pwd_hdr);
	if ((eap_ds->request->type.data = talloc_array(eap_ds->request,
						       uint8_t, sizeof(pwd_hdr))) == NULL) {
	    return 0;
	}
	hdr = (pwd_hdr *)eap_ds->request->type.data;
	EAP_PWD_SET_EXCHANGE(hdr, exch);
	return 1;

    }

    if (pwd_session->in_buf) {
	/*
	 * the last fragment...
	 */
	if ((pwd_session->in_buf_pos + len) > pwd_session->in_buf_len) {
	    RDEBUG2("pwd will not overflow a fragment buffer. Nope, not prudent.");
	    return 0;
	}
	memcpy(pwd_session->in_buf + pwd_session->in_buf_pos, buf, len);
	buf = pwd_session->in_buf;
	len = pwd_session->in_buf_len;
    }

    switch (pwd_session->state) {
	case PWD_STATE_ID_REQ:
	    if (EAP_PWD_GET_EXCHANGE(hdr) != EAP_PWD_EXCH_ID) {
		RDEBUG2("pwd exchange is incorrect: not ID");
		return 0;
	    }
	    id = (pwd_id_packet *)buf;
	    if ((id->prf != EAP_PWD_DEF_PRF) ||
		(id->random_function != EAP_PWD_DEF_RAND_FUN) ||
		(id->prep != EAP_PWD_PREP_NONE) ||
		(memcmp(id->token, (char *)&pwd_session->token, 4)) ||
		(id->group_num != ntohs(pwd_session->group_num))) {
		RDEBUG2("pwd id response is invalid");
		return 0;
	    }
	    /*
	     * we've agreed on the ciphersuite, record it...
	     */
	    ptr = (uint8_t *)&pwd_session->ciphersuite;
	    memcpy(ptr, (char *)&id->group_num, sizeof(uint16_t));
	    ptr += sizeof(uint16_t);
	    *ptr = EAP_PWD_DEF_RAND_FUN;
	    ptr += sizeof(uint8_t);
	    *ptr = EAP_PWD_DEF_PRF;

	    pwd_session->peer_id_len = len - sizeof(pwd_id_packet);
	    if (pwd_session->peer_id_len >= sizeof(pwd_session->peer_id)) {
		RDEBUG2("pwd id response is malformed");
		return 0;
	    }
	    memcpy(pwd_session->peer_id, id->identity,
		    pwd_session->peer_id_len);
	    pwd_session->peer_id[pwd_session->peer_id_len] = '\0';

	    /*
	     * make fake request to get the password for the usable ID
	     */
	    if ((fake = request_alloc_fake(handler->request)) == NULL) {
		RDEBUG("pwd unable to create fake request!");
		return 0;
	    }
	    fake->username = pairmake_packet("User-Name", "", T_OP_EQ);
	    if (!fake->username) {
		RDEBUG("pwd unanable to create value pair for username!");
		request_free(&fake);
		return 0;
	    }
	    memcpy(fake->username->vp_strvalue, pwd_session->peer_id,
		   pwd_session->peer_id_len);
	    fake->username->length = pwd_session->peer_id_len;
	    fake->username->vp_strvalue[fake->username->length] = 0;

	    if ((vp = pairfind(request->config_items, PW_VIRTUAL_SERVER, 0, TAG_ANY)) != NULL) {
		    fake->server = vp->vp_strvalue;
		
	    } else if (inst->conf->virtual_server) {
		    fake->server = inst->conf->virtual_server;
		
	    } /* else fake->server == request->server */
	
	    if ((debug_flag > 0) && fr_log_fp) {
		    RDEBUG("Sending tunneled request");
		
		    debug_pair_list(fake->packet->vps);
		
		    fprintf(fr_log_fp, "server %s {\n",
			    (!fake->server) ? "" : fake->server);
	    }
	
	    /*
	     *	Call authorization recursively, which will
	     *	get the password.
	     */
	    process_authorize(0, fake);
	
	    /*
	     *	Note that we don't do *anything* with the reply
	     *	attributes.
	     */
	    if ((debug_flag > 0) && fr_log_fp) {
		    fprintf(fr_log_fp, "} # server %s\n",
			    (!fake->server) ? "" : fake->server);
		
		    RDEBUG("Got tunneled reply code %d", fake->reply->code);
		
		    debug_pair_list(fake->reply->vps);
	    }

	    if ((pw = pairfind(fake->config_items, PW_CLEARTEXT_PASSWORD, 0, TAG_ANY)) == NULL) {
		DEBUG2("failed to find password for %s to do pwd authentication",
		       pwd_session->peer_id);
		request_free(&fake);
		return 0;
	    }

	    if (compute_password_element(pwd_session, pwd_session->group_num,
					 pw->data.strvalue, strlen(pw->data.strvalue),
					 inst->conf->server_id, strlen(inst->conf->server_id),
					 pwd_session->peer_id, strlen(pwd_session->peer_id),
					 &pwd_session->token)) {
		DEBUG2("failed to obtain password element :-(");
		request_free(&fake);
		return 0;
	    }
	    request_free(&fake);

	    /*
	     * compute our scalar and element
	     */
	    if (compute_scalar_element(pwd_session, inst->bnctx)) {
		DEBUG2("failed to compute server's scalar and element");
		return 0;
	    }
	    if (((x = BN_new()) == NULL) ||
		((y = BN_new()) == NULL)) {
		DEBUG2("server point allocation failed");
		return 0;
	    }
	    /*
	     * element is a point, get both coordinates: x and y
	     */
	    if (!EC_POINT_get_affine_coordinates_GFp(pwd_session->group,
						     pwd_session->my_element, x, y,
						     inst->bnctx)) {
		DEBUG2("server point assignment failed");
		BN_free(x);
		BN_free(y);
		return 0;
	    }
	    /*
	     * construct request
	     */
	    pwd_session->out_buf_len = BN_num_bytes(pwd_session->order) +
		(2 * BN_num_bytes(pwd_session->prime));
	    if ((pwd_session->out_buf = talloc_array(pwd_session, uint8_t,
						     pwd_session->out_buf_len)) == NULL) {
		return 0;
	    }
	    memset(pwd_session->out_buf, 0, pwd_session->out_buf_len);

	    ptr = pwd_session->out_buf;
	    offset = BN_num_bytes(pwd_session->prime) - BN_num_bytes(x);
	    BN_bn2bin(x, ptr + offset);

	    ptr += BN_num_bytes(pwd_session->prime);
	    offset = BN_num_bytes(pwd_session->prime) - BN_num_bytes(y);
	    BN_bn2bin(y, ptr + offset);

	    ptr += BN_num_bytes(pwd_session->prime);
	    offset = BN_num_bytes(pwd_session->order) - BN_num_bytes(pwd_session->my_scalar);
	    BN_bn2bin(pwd_session->my_scalar, ptr + offset);

	    pwd_session->state = PWD_STATE_COMMIT;
	    ret = send_pwd_request(pwd_session, eap_ds);
	    break;
	case PWD_STATE_COMMIT:
	    if (EAP_PWD_GET_EXCHANGE(hdr) != EAP_PWD_EXCH_COMMIT) {
		RDEBUG2("pwd exchange is incorrect: not commit!");
		return 0;
	    }
	    /*
	     * process the peer's commit and generate the shared key, k
	     */
	    if (process_peer_commit(pwd_session, buf, inst->bnctx)) {
		RDEBUG2("failed to process peer's commit");
		return 0;
	    }

	    /*
	     * compute our confirm blob
	     */
	    if (compute_server_confirm(pwd_session, pwd_session->my_confirm, inst->bnctx)) {
		ERROR("rlm_eap_pwd: failed to compute confirm!");
		return 0;
	    }
	    /*
	     * construct a response...which is just our confirm blob
	     */
	    pwd_session->out_buf_len = SHA256_DIGEST_LENGTH;
	    if ((pwd_session->out_buf = talloc_array(pwd_session, uint8_t,
						     pwd_session->out_buf_len)) == NULL) {
		return 0;
	    }
	    memset(pwd_session->out_buf, 0, pwd_session->out_buf_len);
	    memcpy(pwd_session->out_buf, pwd_session->my_confirm, SHA256_DIGEST_LENGTH);

	    pwd_session->state = PWD_STATE_CONFIRM;
	    ret = send_pwd_request(pwd_session, eap_ds);
	    break;
	case PWD_STATE_CONFIRM:
	    if (EAP_PWD_GET_EXCHANGE(hdr) != EAP_PWD_EXCH_CONFIRM) {
		RDEBUG2("pwd exchange is incorrect: not commit!");
		return 0;
	    }
	    if (compute_peer_confirm(pwd_session, peer_confirm, inst->bnctx)) {
		RDEBUG2("pwd exchange cannot compute peer's confirm");
		return 0;
	    }
	    if (memcmp(peer_confirm, buf, SHA256_DIGEST_LENGTH)) {
		RDEBUG2("pwd exchange fails: peer confirm is incorrect!");
		return 0;
	    }
	    if (compute_keys(pwd_session, peer_confirm, msk, emsk)) {
		RDEBUG2("pwd exchange cannot generate (E)MSK!");
		return 0;
	    }
	    eap_ds->request->code = PW_EAP_SUCCESS;
	    /*
	     * return the MSK (in halves)
	     */
	    eap_add_reply(handler->request,
			  "MS-MPPE-Recv-Key", msk, MPPE_KEY_LEN);
	    eap_add_reply(handler->request,
			  "MS-MPPE-Send-Key", msk+MPPE_KEY_LEN, MPPE_KEY_LEN);
	    ret = 1;
	    break;
	default:
	    RDEBUG2("unknown PWD state");
	    return 0;
    }

    /*
     * we processed the buffered fragments, get rid of them
     */
    if (pwd_session->in_buf) {
	    talloc_free(pwd_session->in_buf);
	    pwd_session->in_buf = NULL;
    }

    return ret;
}
Пример #30
0
static int
eap_pwd_initiate (void *instance, eap_handler_t *handler)
{
    pwd_session_t *pwd_session;
    eap_pwd_t *inst = (eap_pwd_t *)instance;
    VALUE_PAIR *vp;
    pwd_id_packet *pack;

    if (!inst || !handler) {
	ERROR("rlm_eap_pwd: initiate, NULL data provided");
	return -1;
    }

    /*
     * make sure the server's been configured properly
     */
    if (!inst->conf->server_id) {
	ERROR("rlm_eap_pwd: server ID is not configured!");
	return -1;
    }
    switch (inst->conf->group) {
	case 19:
	case 20:
	case 21:
	case 25:
	case 26:
	    break;
	default:
	    ERROR("rlm_eap_pwd: group is not supported!");
	    return -1;
    }

    if ((pwd_session = talloc_zero(handler, pwd_session_t)) == NULL) {
	return -1;
    }
    /*
     * set things up so they can be free'd reliably
     */
    pwd_session->group_num = inst->conf->group;
    pwd_session->private_value = NULL;
    pwd_session->peer_scalar = NULL;
    pwd_session->my_scalar = NULL;
    pwd_session->k = NULL;
    pwd_session->my_element = NULL;
    pwd_session->peer_element = NULL;
    pwd_session->group = NULL;
    pwd_session->pwe = NULL;
    pwd_session->order = NULL;
    pwd_session->prime = NULL;

    /*
     * figure out the MTU (basically do what eap-tls does)
     */
    pwd_session->mtu = inst->conf->fragment_size;
    vp = pairfind(handler->request->packet->vps, PW_FRAMED_MTU, 0, TAG_ANY);
    if (vp && ((int)(vp->vp_integer - 9) < pwd_session->mtu)) {
	/*
	 * 9 = 4 (EAPOL header) + 4 (EAP header) + 1 (EAP type)
	 *
	 * the fragmentation code deals with the included length
	 * so we don't need to subtract that here.
	 */
	pwd_session->mtu = vp->vp_integer - 9;
    }

    pwd_session->state = PWD_STATE_ID_REQ;
    pwd_session->in_buf = NULL;
    pwd_session->out_buf_pos = 0;
    handler->opaque = pwd_session;
    handler->free_opaque = free_session;

    /*
     * construct an EAP-pwd-ID/Request
     */
    pwd_session->out_buf_len = sizeof(pwd_id_packet) + strlen(inst->conf->server_id);
    if ((pwd_session->out_buf = talloc_zero_array(pwd_session, uint8_t,
						  pwd_session->out_buf_len)) == NULL) {
	return -1;
    }

    pack = (pwd_id_packet *)pwd_session->out_buf;
    pack->group_num = htons(pwd_session->group_num);
    pack->random_function = EAP_PWD_DEF_RAND_FUN;
    pack->prf = EAP_PWD_DEF_PRF;
    pwd_session->token = random();
    memcpy(pack->token, (char *)&pwd_session->token, 4);
    pack->prep = EAP_PWD_PREP_NONE;
    strcpy(pack->identity, inst->conf->server_id);

    handler->stage = AUTHENTICATE;

    return send_pwd_request(pwd_session, handler->eap_ds);
}