Пример #1
0
/**
 * Import an existing talloc pointer into a Python object.
 */
_PUBLIC_ PyObject *pytalloc_steal_ex(PyTypeObject *py_type, TALLOC_CTX *mem_ctx,
				     void *ptr)
{
	PyTypeObject *BaseObjectType = pytalloc_GetBaseObjectType();
	PyTypeObject *ObjectType = pytalloc_GetObjectType();

	if (mem_ctx == NULL) {
		return PyErr_NoMemory();
	}

	if (PyType_IsSubtype(py_type, BaseObjectType)) {
		pytalloc_BaseObject *ret
			= (pytalloc_BaseObject *)py_type->tp_alloc(py_type, 0);

		ret->talloc_ctx = talloc_new(NULL);
		if (ret->talloc_ctx == NULL) {
			return NULL;
		}

		/*
		 * This allows us to keep multiple references to this object -
		 * we only reference this context, which is per ptr, not the
		 * talloc_ctx, which is per pytalloc_Object
		 */
		if (talloc_steal(ret->talloc_ctx, mem_ctx) == NULL) {
			return NULL;
		}
		ret->talloc_ptr_ctx = mem_ctx;
		talloc_set_name_const(ret->talloc_ctx, py_type->tp_name);
		ret->ptr = ptr;
		return (PyObject *)ret;

	} else if (PyType_IsSubtype(py_type, ObjectType)) {
		pytalloc_Object *ret
			= (pytalloc_Object *)py_type->tp_alloc(py_type, 0);

		ret->talloc_ctx = talloc_new(NULL);
		if (ret->talloc_ctx == NULL) {
			return NULL;
		}

		if (talloc_steal(ret->talloc_ctx, mem_ctx) == NULL) {
			return NULL;
		}
		talloc_set_name_const(ret->talloc_ctx, py_type->tp_name);
		ret->ptr = ptr;
		return (PyObject *)ret;
	} else {
		PyErr_SetString(PyExc_RuntimeError,
				"pytalloc_steal_ex() called for object type "
				"not based on talloc");
		return NULL;
	}
}
Пример #2
0
void *_policy_handle_create(struct pipes_struct *p, struct policy_handle *hnd,
			    uint32_t access_granted, size_t data_size,
			    const char *type, NTSTATUS *pstatus)
{
	struct dcesrv_handle *rpc_hnd;
	void *data;

	if (p->pipe_handles->count > MAX_OPEN_POLS) {
		DEBUG(0, ("ERROR: Too many handles (%d) for RPC connection %s\n",
			  (int) p->pipe_handles->count,
			  get_pipe_name_from_syntax(talloc_tos(),
						    &p->contexts->syntax)));
		*pstatus = NT_STATUS_INSUFFICIENT_RESOURCES;
		return NULL;
	}

	data = talloc_size(talloc_tos(), data_size);
	if (data == NULL) {
		*pstatus = NT_STATUS_NO_MEMORY;
		return NULL;
	}
	talloc_set_name_const(data, type);

	rpc_hnd = create_rpc_handle_internal(p, hnd, data);
	if (rpc_hnd == NULL) {
		TALLOC_FREE(data);
		*pstatus = NT_STATUS_NO_MEMORY;
		return NULL;
	}
	rpc_hnd->access_granted = access_granted;
	*pstatus = NT_STATUS_OK;
	return data;
}
Пример #3
0
/** Setup an LDAP sync request
 *
 * Allocates a request, with request/reply packets.
 *
 * Sets various fields in the request->packet with information from the file descriptor
 * we received from libldap.
 *
 * @param[in] listen	The common listener encapsulating the libldap fd.
 * @param[in] inst	of the proto_ldap_sync module.
 * @param[in] sync_id 	the unique identifier of the sync.
 * @return
 *	- A new request on success.
 *	- NULL on error.
 */
static REQUEST *proto_ldap_request_setup(rad_listen_t *listen, proto_ldap_inst_t *inst, int sync_id)
{
	TALLOC_CTX		*ctx;
	RADIUS_PACKET		*packet;
	REQUEST			*request;

	ctx = talloc_pool(NULL, main_config->talloc_pool_size);
	if (!ctx) return NULL;
	talloc_set_name_const(ctx, "ldap_inst_pool");

	packet = fr_radius_alloc(ctx, false);
	packet->sockfd = listen->fd;
	packet->id = sync_id;
	packet->src_ipaddr = inst->dst_ipaddr;
	packet->src_port = inst->dst_port;
	packet->dst_ipaddr = inst->src_ipaddr;
	packet->dst_port = inst->src_port;
	gettimeofday(&packet->timestamp, NULL);

	request = request_setup(ctx, listen, packet, inst->client, NULL);
	if (!request) return NULL;

	request->process = request_queued;

	return request;
}
Пример #4
0
/*
  convert a dom_sid to a string
*/
char *dom_sid_string(TALLOC_CTX *mem_ctx, const struct dom_sid *sid)
{
	char buf[DOM_SID_STR_BUFLEN];
	char *result;
	int len;

	len = dom_sid_string_buf(sid, buf, sizeof(buf));

	if (len+1 > sizeof(buf)) {
		return talloc_strdup(mem_ctx, "(SID ERR)");
	}

	/*
	 * Avoid calling strlen (via talloc_strdup), we already have
	 * the length
	 */
	result = (char *)talloc_memdup(mem_ctx, buf, len+1);
	if (result == NULL) {
		return NULL;
	}

	/*
	 * beautify the talloc_report output
	 */
	talloc_set_name_const(result, result);
	return result;
}
Пример #5
0
struct tsocket_context *_tsocket_context_create(TALLOC_CTX *mem_ctx,
						const struct tsocket_context_ops *ops,
						void *pstate,
						size_t psize,
						const char *type,
						const char *location)
{
	void **ppstate = (void **)pstate;
	struct tsocket_context *sock;

	sock = talloc_zero(mem_ctx, struct tsocket_context);
	if (!sock) {
		return NULL;
	}
	sock->ops = ops;
	sock->location = location;
	sock->private_data = talloc_size(sock, psize);
	if (!sock->private_data) {
		talloc_free(sock);
		return NULL;
	}
	talloc_set_name_const(sock->private_data, type);

	talloc_set_destructor(sock, tsocket_context_destructor);

	*ppstate = sock->private_data;
	return sock;
}
Пример #6
0
struct tsocket_address *_tsocket_address_create(TALLOC_CTX *mem_ctx,
						const struct tsocket_address_ops *ops,
						void *pstate,
						size_t psize,
						const char *type,
						const char *location)
{
	void **ppstate = (void **)pstate;
	struct tsocket_address *addr;

	addr = talloc_zero(mem_ctx, struct tsocket_address);
	if (!addr) {
		return NULL;
	}
	addr->ops = ops;
	addr->location = location;
	addr->private_data = talloc_size(addr, psize);
	if (!addr->private_data) {
		talloc_free(addr);
		return NULL;
	}
	talloc_set_name_const(addr->private_data, type);

	*ppstate = addr->private_data;
	return addr;
}
Пример #7
0
void *_policy_handle_create(struct pipes_struct *p, struct policy_handle *hnd,
                            uint32_t access_granted, size_t data_size,
                            const char *type, NTSTATUS *pstatus)
{
    struct policy *pol;
    void *data;

    if (p->pipe_handles->count > MAX_OPEN_POLS) {
        DEBUG(0, ("policy_handle_create: ERROR: too many handles (%d) "
                  "on pipe %s.\n", (int)p->pipe_handles->count,
                  get_pipe_name_from_syntax(talloc_tos(), &p->syntax)));
        *pstatus = NT_STATUS_INSUFFICIENT_RESOURCES;
        return NULL;
    }

    data = talloc_size(talloc_tos(), data_size);
    if (data == NULL) {
        *pstatus = NT_STATUS_NO_MEMORY;
        return NULL;
    }
    talloc_set_name_const(data, type);

    pol = create_policy_hnd_internal(p, hnd, data);
    if (pol == NULL) {
        TALLOC_FREE(data);
        *pstatus = NT_STATUS_NO_MEMORY;
        return NULL;
    }
    pol->access_granted = access_granted;
    *pstatus = NT_STATUS_OK;
    return data;
}
Пример #8
0
/****************************************************************
Callback to get the PAC_LOGON_INFO from the blob
****************************************************************/
static NTSTATUS kerberos_fetch_pac(struct auth4_context *auth_ctx,
				   TALLOC_CTX *mem_ctx,
				   struct smb_krb5_context *smb_krb5_context,
				   DATA_BLOB *pac_blob,
				   const char *princ_name,
				   const struct tsocket_address *remote_address,
				   uint32_t session_info_flags,
				   struct auth_session_info **session_info)
{
	TALLOC_CTX *tmp_ctx;
	struct PAC_DATA *pac_data = NULL;
	struct PAC_DATA_CTR *pac_data_ctr = NULL;
	NTSTATUS status = NT_STATUS_INTERNAL_ERROR;

	tmp_ctx = talloc_new(mem_ctx);
	if (!tmp_ctx) {
		return NT_STATUS_NO_MEMORY;
	}

	if (pac_blob) {
		status = kerberos_decode_pac(tmp_ctx,
					     *pac_blob,
					     NULL,
					     NULL,
					     NULL,
					     NULL,
					     0,
					     &pac_data);
		if (!NT_STATUS_IS_OK(status)) {
			goto done;
		}
	}

	pac_data_ctr = talloc(mem_ctx, struct PAC_DATA_CTR);
	if (pac_data_ctr == NULL) {
		status = NT_STATUS_NO_MEMORY;
		goto done;
	}

	talloc_set_name_const(pac_data_ctr, "struct PAC_DATA_CTR");

	pac_data_ctr->pac_data = talloc_steal(pac_data_ctr, pac_data);
	pac_data_ctr->pac_blob = data_blob_talloc(pac_data_ctr,
						  pac_blob->data,
						  pac_blob->length);

	auth_ctx->private_data = talloc_steal(auth_ctx, pac_data_ctr);

	*session_info = talloc_zero(mem_ctx, struct auth_session_info);
	if (!*session_info) {
		status = NT_STATUS_NO_MEMORY;
		goto done;
	}
	status = NT_STATUS_OK;

done:
	TALLOC_FREE(tmp_ctx);

	return status;
}
Пример #9
0
/**
 * Import an existing talloc pointer into a Python object, leaving the
 * original parent, and creating a reference to the object in the python
 * object.
 *
 * We remember the object we hold the reference to (a
 * possibly-non-talloc pointer), the existing parent (typically the
 * start of the array) and the new referenced parent.  That way we can
 * cope with the fact that we will have multiple parents, one per time
 * python sees the object.
 */
_PUBLIC_ PyObject *pytalloc_reference_ex(PyTypeObject *py_type,
					 TALLOC_CTX *mem_ctx, void *ptr)
{
	PyTypeObject *BaseObjectType = pytalloc_GetBaseObjectType();
	PyTypeObject *ObjectType = pytalloc_GetObjectType();

	if (mem_ctx == NULL) {
		return PyErr_NoMemory();
	}

	if (PyType_IsSubtype(py_type, BaseObjectType)) {
		pytalloc_BaseObject *ret
			= (pytalloc_BaseObject *)py_type->tp_alloc(py_type, 0);
		ret->talloc_ctx = talloc_new(NULL);
		if (ret->talloc_ctx == NULL) {
			return NULL;
		}
		if (talloc_reference(ret->talloc_ctx, mem_ctx) == NULL) {
			return NULL;
		}
		talloc_set_name_const(ret->talloc_ctx, py_type->tp_name);
		ret->talloc_ptr_ctx = mem_ctx;
		ret->ptr = ptr;
		return (PyObject *)ret;
	} else if (PyType_IsSubtype(py_type, ObjectType)) {
		pytalloc_Object *ret
			= (pytalloc_Object *)py_type->tp_alloc(py_type, 0);
		ret->talloc_ctx = talloc_new(NULL);
		if (ret->talloc_ctx == NULL) {
			return NULL;
		}
		if (talloc_reference(ret->talloc_ctx, mem_ctx) == NULL) {
			return NULL;
		}
		talloc_set_name_const(ret->talloc_ctx, py_type->tp_name);
		ret->ptr = ptr;
		return (PyObject *)ret;
	} else {
		PyErr_SetString(PyExc_RuntimeError,
				"pytalloc_reference_ex() called for object type "
				"not based on talloc");
		return NULL;
	}
}
Пример #10
0
_PUBLIC_ bool cli_credentials_set_old_password(struct cli_credentials *cred, 
				      const char *val, 
				      enum credentials_obtained obtained)
{
	cred->old_password = talloc_strdup(cred, val);
	if (cred->old_password) {
		/* Don't print the actual password in talloc memory dumps */
		talloc_set_name_const(cred->old_password, "password set via cli_credentials_set_old_password");
	}
	return true;
}
Пример #11
0
char* ez_strchompc (char *string, char c) {
  
    char *s;

    ez_return_val_if_fail (string != NULL, NULL);

    for (s = string + strlen (string) - 1; s >= string && (uchar)*s == c; s--)
        *s = '\0';

    talloc_set_name_const (string, string);
    return string;
}
Пример #12
0
char* ez_strchugc (char *string, char c) {

    uchar *s;

    ez_return_val_if_fail (string != NULL, NULL);

    for (s = (uchar*) string; *s && (uchar)*s == c; s++)
    ;;

    memmove (string, s, strlen ((char *) s) + 1);

    talloc_set_name_const (string, string);
    return string;
}
Пример #13
0
char* ez_strchug (char *string) {

    uchar *start;

    ez_return_val_if_fail (string != NULL, NULL);

    for (start = (uchar*) string; *start && isspace (*start); start++)
    ;;

    memmove (string, start, strlen ((char *) start) + 1);

    talloc_set_name_const (string, string);
    return string;
}
Пример #14
0
/*
  make a remote ctdb call - async send. Called in daemon context.

  This constructs a ctdb_call request and queues it for processing. 
  This call never blocks.
*/
struct ctdb_call_state *ctdb_daemon_call_send_remote(struct ctdb_db_context *ctdb_db, 
						     struct ctdb_call *call, 
						     struct ctdb_ltdb_header *header)
{
	uint32_t len;
	struct ctdb_call_state *state;
	struct ctdb_context *ctdb = ctdb_db->ctdb;

	state = talloc_zero(ctdb_db, struct ctdb_call_state);
	CTDB_NO_MEMORY_NULL(ctdb, state);

	len = offsetof(struct ctdb_req_call, data) + call->key.dsize + call->call_data.dsize;
	state->c = ctdb->methods->allocate_pkt(state, len);
	CTDB_NO_MEMORY_NULL(ctdb, state->c);
	talloc_set_name_const(state->c, "req_call packet");

	state->c->hdr.length    = len;
	state->c->hdr.ctdb_magic = CTDB_MAGIC;
	state->c->hdr.ctdb_version = CTDB_VERSION;
	state->c->hdr.operation = CTDB_REQ_CALL;
	state->c->hdr.destnode  = header->dmaster;
	state->c->hdr.srcnode   = ctdb->vnn;
	/* this limits us to 16k outstanding messages - not unreasonable */
	state->c->hdr.reqid     = idr_get_new(ctdb->idr, state, 0xFFFF);
	state->c->flags         = call->flags;
	state->c->db_id         = ctdb_db->db_id;
	state->c->callid        = call->call_id;
	state->c->keylen        = call->key.dsize;
	state->c->calldatalen   = call->call_data.dsize;
	memcpy(&state->c->data[0], call->key.dptr, call->key.dsize);
	memcpy(&state->c->data[call->key.dsize], 
	       call->call_data.dptr, call->call_data.dsize);
	state->call                = *call;
	state->call.call_data.dptr = &state->c->data[call->key.dsize];
	state->call.key.dptr       = &state->c->data[0];

	state->node   = ctdb->nodes[header->dmaster];
	state->state  = CTDB_CALL_WAIT;
	state->header = *header;
	state->ctdb_db = ctdb_db;

	talloc_set_destructor(state, ctdb_call_destructor);

	ctdb_queue_packet(ctdb, &state->c->hdr);

	event_add_timed(ctdb->ev, state, timeval_current_ofs(CTDB_REQ_TIMEOUT, 0), 
			ctdb_call_timeout, state);
	return state;
}
/**
 * Import an existing talloc pointer into a Python object.
 */
_PUBLIC_ PyObject *pytalloc_steal_ex(PyTypeObject *py_type, TALLOC_CTX *mem_ctx,
						   void *ptr)
{
	pytalloc_Object *ret = (pytalloc_Object *)py_type->tp_alloc(py_type, 0);
	ret->talloc_ctx = talloc_new(NULL);
	if (ret->talloc_ctx == NULL) {
		return NULL;
	}
	if (talloc_steal(ret->talloc_ctx, mem_ctx) == NULL) {
		return NULL;
	}
	talloc_set_name_const(ret->talloc_ctx, py_type->tp_name);
	ret->ptr = ptr;
	return (PyObject *)ret;
}
Пример #16
0
char *server_id_str(TALLOC_CTX *mem_ctx, const struct server_id *id)
{
	struct server_id_buf tmp;
	char *result;

	result = talloc_strdup(mem_ctx, server_id_str_buf(*id, &tmp));
	if (result == NULL) {
		return NULL;
	}

	/*
	 * beautify the talloc_report output
	 */
	talloc_set_name_const(result, result);
	return result;
}
Пример #17
0
char* ez_strconcat (const char *string1, ...) {

    size_t l;     
    va_list args;
    char *s;
    char *concat;
    char *ptr;

    ez_return_val_if_fail (string1 != NULL, NULL);

    l = 1 + strlen (string1);

    va_start (args, string1);
    s = va_arg (args, char*);

    while (s) {
        l += strlen (s);
        s = va_arg (args, char*);
    }
   
    va_end (args);

    concat = ez_new (char, l);

    ptr = concat;

    ptr = ez_stpcpy (ptr, string1);
     
    va_start (args, string1);
    s = va_arg (args, char*);
    
    while (s) {
        ptr = ez_stpcpy (ptr, s);
        s = va_arg (args, char*);
    }
    
    va_end (args);

    talloc_set_name_const (concat, concat);
    return concat;
}
Пример #18
0
static bool test_free_children(void)
{
	void *root;
	const char *p1, *p2, *name, *name2;

	talloc_enable_null_tracking();
	root = talloc_new(NULL);
	p1 = talloc_strdup(root, "foo1");
	p2 = talloc_strdup(p1, "foo2");

	talloc_set_name(p1, "%s", "testname");
	talloc_free_children(p1);
	/* check its still a valid talloc ptr */
	talloc_get_size(talloc_get_name(p1));
	if (strcmp(talloc_get_name(p1), "testname") != 0) {
		return false;
	}

	talloc_set_name(p1, "%s", "testname");
	name = talloc_get_name(p1);
	talloc_free_children(p1);
	/* check its still a valid talloc ptr */
	talloc_get_size(talloc_get_name(p1));
	torture_assert("name", name == talloc_get_name(p1), "name ptr changed");
	torture_assert("namecheck", strcmp(talloc_get_name(p1), "testname") == 0,
		       "wrong name");
	CHECK_BLOCKS("name1", p1, 2);

	/* note that this does not free the old child name */
	talloc_set_name_const(p1, "testname2");
	name2 = talloc_get_name(p1);
	/* but this does */
	talloc_free_children(p1);
	torture_assert("namecheck", strcmp(talloc_get_name(p1), "testname2") == 0,
		       "wrong name");
	CHECK_BLOCKS("name1", p1, 1);

	talloc_report_full(root, stdout);
	talloc_free(root);
	return true;
}
Пример #19
0
/**
 * Allocate for @context a new node with given @name and @type.  This
 * function returns NULL if there's not enough memory.
 */
Node *new_node(TALLOC_CTX *context, const char *name, ssize_t length, int type)
{
	Node *node;

	node = talloc_zero(context, Node);
	if (node == NULL)
		return NULL;

	if (length < 0)
		length = strlen(name);

	node->name = talloc_strndup(node, name, length);
	if (node->name == NULL)
		return NULL;

	talloc_set_name_const(node->name, "$name");

	node->type   = type;
	node->parent = node;

	return node;
}
Пример #20
0
/*
  send a redirect reply
*/
static void ctdb_call_send_redirect(struct ctdb_context *ctdb, 
				    struct ctdb_req_call *c, 
				    struct ctdb_ltdb_header *header)
{
	struct ctdb_reply_redirect *r;

	r = ctdb->methods->allocate_pkt(ctdb, sizeof(*r));
	CTDB_NO_MEMORY_FATAL(ctdb, r);
	talloc_set_name_const(r, "send_redirect packet");
	r->hdr.length = sizeof(*r);
	r->hdr.ctdb_magic = CTDB_MAGIC;
	r->hdr.ctdb_version = CTDB_VERSION;
	r->hdr.operation = CTDB_REPLY_REDIRECT;
	r->hdr.destnode  = c->hdr.srcnode;
	r->hdr.srcnode   = ctdb->vnn;
	r->hdr.reqid     = c->hdr.reqid;
	r->dmaster       = header->dmaster;

	ctdb_queue_packet(ctdb, &r->hdr);

	talloc_free(r);
}
Пример #21
0
_PUBLIC_ bool cli_credentials_set_password(struct cli_credentials *cred, 
				  const char *val, 
				  enum credentials_obtained obtained)
{
	if (obtained >= cred->password_obtained) {
		cred->password_tries = 0;
		cred->password = talloc_strdup(cred, val);
		if (cred->password) {
			/* Don't print the actual password in talloc memory dumps */
			talloc_set_name_const(cred->password, "password set via cli_credentials_set_password");
		}
		cred->password_obtained = obtained;
		cli_credentials_invalidate_ccache(cred, cred->password_obtained);

		cred->nt_hash = NULL;
		cred->lm_response = data_blob(NULL, 0);
		cred->nt_response = data_blob(NULL, 0);
		return true;
	}

	return false;
}
Пример #22
0
/*
  message handler for when we are in daemon mode. This redirects the message
  to the right client
 */
static void daemon_message_handler(uint64_t srvid, TDB_DATA data,
				   void *private_data)
{
	struct ctdb_client *client = talloc_get_type(private_data, struct ctdb_client);
	struct ctdb_req_message *r;
	int len;

	/* construct a message to send to the client containing the data */
	len = offsetof(struct ctdb_req_message, data) + data.dsize;
	r = ctdbd_allocate_pkt(client->ctdb, client->ctdb, CTDB_REQ_MESSAGE,
			       len, struct ctdb_req_message);
	CTDB_NO_MEMORY_VOID(client->ctdb, r);

	talloc_set_name_const(r, "req_message packet");

	r->srvid         = srvid;
	r->datalen       = data.dsize;
	memcpy(&r->data[0], data.dptr, data.dsize);

	daemon_queue_send(client, &r->hdr);

	talloc_free(r);
}
Пример #23
0
struct tevent_req *_tevent_req_create(TALLOC_CTX *mem_ctx,
				    void *pdata,
				    size_t data_size,
				    const char *type,
				    const char *location)
{
	struct tevent_req *req;
	void **ppdata = (void **)pdata;
	void *data;

	req = talloc_zero(mem_ctx, struct tevent_req);
	if (req == NULL) {
		return NULL;
	}
	req->internal.private_type	= type;
	req->internal.create_location	= location;
	req->internal.finish_location	= NULL;
	req->internal.state		= TEVENT_REQ_IN_PROGRESS;
	req->internal.trigger		= tevent_create_immediate(req);
	if (!req->internal.trigger) {
		talloc_free(req);
		return NULL;
	}
	req->internal.defer_callback_ev	= NULL;

	data = talloc_zero_size(req, data_size);
	if (data == NULL) {
		talloc_free(req);
		return NULL;
	}
	talloc_set_name_const(data, type);

	req->data = data;

	*ppdata = data;
	return req;
}
Пример #24
0
static void ctdb_send_error(struct ctdb_context *ctdb, 
			    struct ctdb_req_header *hdr, uint32_t status,
			    const char *fmt, ...)
{
	va_list ap;
	struct ctdb_reply_error *r;
	char *msg;
	int msglen, len;

	va_start(ap, fmt);
	msg = talloc_vasprintf(ctdb, fmt, ap);
	if (msg == NULL) {
		ctdb_fatal(ctdb, "Unable to allocate error in ctdb_send_error\n");
	}
	va_end(ap);

	msglen = strlen(msg)+1;
	len = offsetof(struct ctdb_reply_error, msg);
	r = ctdb->methods->allocate_pkt(msg, len + msglen);
	CTDB_NO_MEMORY_FATAL(ctdb, r);
	talloc_set_name_const(r, "send_error packet");

	r->hdr.length    = len + msglen;
	r->hdr.ctdb_magic = CTDB_MAGIC;
	r->hdr.ctdb_version = CTDB_VERSION;
	r->hdr.operation = CTDB_REPLY_ERROR;
	r->hdr.destnode  = hdr->srcnode;
	r->hdr.srcnode   = ctdb->vnn;
	r->hdr.reqid     = hdr->reqid;
	r->status        = status;
	r->msglen        = msglen;
	memcpy(&r->msg[0], msg, msglen);

	ctdb_queue_packet(ctdb, &r->hdr);

	talloc_free(msg);
}
Пример #25
0
struct dcerpc_binding_handle *_dcerpc_binding_handle_create(TALLOC_CTX *mem_ctx,
					const struct dcerpc_binding_handle_ops *ops,
					const struct GUID *object,
					const struct ndr_interface_table *table,
					void *pstate,
					size_t psize,
					const char *type,
					const char *location)
{
	struct dcerpc_binding_handle *h;
	void **ppstate = (void **)pstate;
	void *state;

	h = talloc_zero(mem_ctx, struct dcerpc_binding_handle);
	if (h == NULL) {
		return NULL;
	}
	h->ops		= ops;
	h->location	= location;
	h->object	= object;
	h->table	= table;

	state = talloc_zero_size(h, psize);
	if (state == NULL) {
		talloc_free(h);
		return NULL;
	}
	talloc_set_name_const(state, type);

	h->private_data = state;

	talloc_set_destructor(h, dcerpc_binding_handle_destructor);

	*ppstate = state;
	return h;
}
Пример #26
0
/*
  send a dmaster request (give another node the dmaster for a record)

  This is always sent to the lmaster, which ensures that the lmaster
  always knows who the dmaster is. The lmaster will then send a
  CTDB_REPLY_DMASTER to the new dmaster
*/
static void ctdb_call_send_dmaster(struct ctdb_db_context *ctdb_db, 
				   struct ctdb_req_call *c, 
				   struct ctdb_ltdb_header *header,
				   TDB_DATA *key, TDB_DATA *data)
{
	struct ctdb_req_dmaster *r;
	struct ctdb_context *ctdb = ctdb_db->ctdb;
	int len;
	
	len = offsetof(struct ctdb_req_dmaster, data) + key->dsize + data->dsize;
	r = ctdb->methods->allocate_pkt(ctdb, len);
	CTDB_NO_MEMORY_FATAL(ctdb, r);
	talloc_set_name_const(r, "send_dmaster packet");
	r->hdr.length    = len;
	r->hdr.ctdb_magic = CTDB_MAGIC;
	r->hdr.ctdb_version = CTDB_VERSION;
	r->hdr.operation = CTDB_REQ_DMASTER;
	r->hdr.destnode  = ctdb_lmaster(ctdb, key);
	r->hdr.srcnode   = ctdb->vnn;
	r->hdr.reqid     = c->hdr.reqid;
	r->db_id         = c->db_id;
	r->dmaster       = c->hdr.srcnode;
	r->keylen        = key->dsize;
	r->datalen       = data->dsize;
	memcpy(&r->data[0], key->dptr, key->dsize);
	memcpy(&r->data[key->dsize], data->dptr, data->dsize);

	/* XXX - probably not necessary when lmaster==dmaster
	   update the ltdb to record the new dmaster */
	header->dmaster = r->hdr.destnode;
	ctdb_ltdb_store(ctdb_db, *key, header, *data);
	
	ctdb_queue_packet(ctdb, &r->hdr);

	talloc_free(r);
}
Пример #27
0
/*
  miscellaneous tests to try to get a higher test coverage percentage
*/
static bool test_misc(void)
{
	void *root, *p1;
	char *p2;
	double *d;
	const char *name;

	printf("test: misc\n# MISCELLANEOUS\n");

	root = talloc_new(NULL);

	p1 = talloc_size(root, 0x7fffffff);
	torture_assert("misc", !p1, "failed: large talloc allowed\n");

	p1 = talloc_strdup(root, "foo");
	talloc_increase_ref_count(p1);
	talloc_increase_ref_count(p1);
	talloc_increase_ref_count(p1);
	CHECK_BLOCKS("misc", p1, 1);
	CHECK_BLOCKS("misc", root, 2);
	talloc_unlink(NULL, p1);
	CHECK_BLOCKS("misc", p1, 1);
	CHECK_BLOCKS("misc", root, 2);
	talloc_unlink(NULL, p1);
	CHECK_BLOCKS("misc", p1, 1);
	CHECK_BLOCKS("misc", root, 2);
	p2 = talloc_strdup(p1, "foo");
	torture_assert("misc", talloc_unlink(root, p2) == -1,
				   "failed: talloc_unlink() of non-reference context should return -1\n");
	torture_assert("misc", talloc_unlink(p1, p2) == 0,
		"failed: talloc_unlink() of parent should succeed\n");
	talloc_unlink(NULL, p1);
	CHECK_BLOCKS("misc", p1, 1);
	CHECK_BLOCKS("misc", root, 2);

	name = talloc_set_name(p1, "my name is %s", "foo");
	torture_assert_str_equal("misc", talloc_get_name(p1), "my name is foo",
		"failed: wrong name after talloc_set_name(my name is foo)");
	torture_assert_str_equal("misc", talloc_get_name(p1), name,
		"failed: wrong name after talloc_set_name(my name is foo)");
	CHECK_BLOCKS("misc", p1, 2);
	CHECK_BLOCKS("misc", root, 3);

	talloc_set_name_const(p1, NULL);
	torture_assert_str_equal ("misc", talloc_get_name(p1), "UNNAMED",
		"failed: wrong name after talloc_set_name(NULL)");
	CHECK_BLOCKS("misc", p1, 2);
	CHECK_BLOCKS("misc", root, 3);

	torture_assert("misc", talloc_free(NULL) == -1, 
				   "talloc_free(NULL) should give -1\n");

	talloc_set_destructor(p1, fail_destructor);
	torture_assert("misc", talloc_free(p1) == -1, 
		"Failed destructor should cause talloc_free to fail\n");
	talloc_set_destructor(p1, NULL);

	talloc_report(root, stderr);


	p2 = (char *)talloc_zero_size(p1, 20);
	torture_assert("misc", p2[19] == 0, "Failed to give zero memory\n");
	talloc_free(p2);

	torture_assert("misc", talloc_strdup(root, NULL) == NULL,
		"failed: strdup on NULL should give NULL\n");

	p2 = talloc_strndup(p1, "foo", 2);
	torture_assert("misc", strcmp("fo", p2) == 0, 
				   "strndup doesn't work\n");
	p2 = talloc_asprintf_append_buffer(p2, "o%c", 'd');
	torture_assert("misc", strcmp("food", p2) == 0, 
				   "talloc_asprintf_append_buffer doesn't work\n");
	CHECK_BLOCKS("misc", p2, 1);
	CHECK_BLOCKS("misc", p1, 3);

	p2 = talloc_asprintf_append_buffer(NULL, "hello %s", "world");
	torture_assert("misc", strcmp("hello world", p2) == 0,
		"talloc_asprintf_append_buffer doesn't work\n");
	CHECK_BLOCKS("misc", p2, 1);
	CHECK_BLOCKS("misc", p1, 3);
	talloc_free(p2);

	d = talloc_array(p1, double, 0x20000000);
	torture_assert("misc", !d, "failed: integer overflow not detected\n");

	d = talloc_realloc(p1, d, double, 0x20000000);
	torture_assert("misc", !d, "failed: integer overflow not detected\n");

	talloc_free(p1);
	CHECK_BLOCKS("misc", root, 1);

	p1 = talloc_named(root, 100, "%d bytes", 100);
	CHECK_BLOCKS("misc", p1, 2);
	CHECK_BLOCKS("misc", root, 3);
	talloc_unlink(root, p1);

	p1 = talloc_init("%d bytes", 200);
	p2 = talloc_asprintf(p1, "my test '%s'", "string");
	torture_assert_str_equal("misc", p2, "my test 'string'",
		"failed: talloc_asprintf(\"my test '%%s'\", \"string\") gave: \"%s\"");
	CHECK_BLOCKS("misc", p1, 3);
	CHECK_SIZE("misc", p2, 17);
	CHECK_BLOCKS("misc", root, 1);
	talloc_unlink(NULL, p1);

	p1 = talloc_named_const(root, 10, "p1");
	p2 = (char *)talloc_named_const(root, 20, "p2");
	(void)talloc_reference(p1, p2);
	talloc_report_full(root, stderr);
	talloc_unlink(root, p2);
	talloc_report_full(root, stderr);
	CHECK_BLOCKS("misc", p2, 1);
	CHECK_BLOCKS("misc", p1, 2);
	CHECK_BLOCKS("misc", root, 3);
	talloc_unlink(p1, p2);
	talloc_unlink(root, p1);

	p1 = talloc_named_const(root, 10, "p1");
	p2 = (char *)talloc_named_const(root, 20, "p2");
	(void)talloc_reference(NULL, p2);
	talloc_report_full(root, stderr);
	talloc_unlink(root, p2);
	talloc_report_full(root, stderr);
	CHECK_BLOCKS("misc", p2, 1);
	CHECK_BLOCKS("misc", p1, 1);
	CHECK_BLOCKS("misc", root, 2);
	talloc_unlink(NULL, p2);
	talloc_unlink(root, p1);

	/* Test that talloc_unlink is a no-op */

	torture_assert("misc", talloc_unlink(root, NULL) == -1,
		"failed: talloc_unlink(root, NULL) == -1\n");

	talloc_report(root, stderr);
	talloc_report(NULL, stderr);

	CHECK_SIZE("misc", root, 0);

	talloc_free(root);

	CHECK_SIZE("misc", NULL, 0);

	talloc_enable_null_tracking_no_autofree();
	talloc_enable_leak_report();
	talloc_enable_leak_report_full();

	printf("success: misc\n");

	return true;
}
Пример #28
0
/*
  queue a packet for sending
*/
int ctdb_queue_send(struct ctdb_queue *queue, uint8_t *data, uint32_t length)
{
	struct ctdb_req_header *hdr = (struct ctdb_req_header *)data;
	struct ctdb_queue_pkt *pkt;
	uint32_t length2, full_length;

	if (queue->alignment) {
		/* enforce the length and alignment rules from the tcp packet allocator */
		length2 = (length+(queue->alignment-1)) & ~(queue->alignment-1);
		*(uint32_t *)data = length2;
	} else {
		length2 = length;
	}

	if (length2 != length) {
		memset(data+length, 0, length2-length);
	}

	full_length = length2;
	
	/* if the queue is empty then try an immediate write, avoiding
	   queue overhead. This relies on non-blocking sockets */
	if (queue->out_queue == NULL && queue->fd != -1 &&
	    !(queue->ctdb->flags & CTDB_FLAG_TORTURE)) {
		ssize_t n = write(queue->fd, data, length2);
		if (n == -1 && errno != EAGAIN && errno != EWOULDBLOCK) {
			talloc_free(queue->fde);
			queue->fde = NULL;
			queue->fd = -1;
			tevent_schedule_immediate(queue->im, queue->ctdb->ev,
						  queue_dead, queue);
			/* yes, we report success, as the dead node is 
			   handled via a separate event */
			return 0;
		}
		if (n > 0) {
			data += n;
			length2 -= n;
		}
		if (length2 == 0) return 0;
	}

	pkt = talloc_size(
		queue, offsetof(struct ctdb_queue_pkt, buf) + length2);
	CTDB_NO_MEMORY(queue->ctdb, pkt);
	talloc_set_name_const(pkt, "struct ctdb_queue_pkt");

	pkt->data = pkt->buf;
	memcpy(pkt->data, data, length2);

	pkt->length = length2;
	pkt->full_length = full_length;

	if (queue->out_queue == NULL && queue->fd != -1) {
		TEVENT_FD_WRITEABLE(queue->fde);
	}

	DLIST_ADD_END(queue->out_queue, pkt, NULL);

	queue->out_queue_length++;

	if (queue->ctdb->tunable.verbose_memory_names != 0) {
		switch (hdr->operation) {
		case CTDB_REQ_CONTROL: {
			struct ctdb_req_control_old *c = (struct ctdb_req_control_old *)hdr;
			talloc_set_name(pkt, "ctdb_queue_pkt: %s control opcode=%u srvid=%llu datalen=%u",
					queue->name, (unsigned)c->opcode, (unsigned long long)c->srvid, (unsigned)c->datalen);
			break;
		}
		case CTDB_REQ_MESSAGE: {
			struct ctdb_req_message_old *m = (struct ctdb_req_message_old *)hdr;
			talloc_set_name(pkt, "ctdb_queue_pkt: %s message srvid=%llu datalen=%u",
					queue->name, (unsigned long long)m->srvid, (unsigned)m->datalen);
			break;
		}
		default:
			talloc_set_name(pkt, "ctdb_queue_pkt: %s operation=%u length=%u src=%u dest=%u",
					queue->name, (unsigned)hdr->operation, (unsigned)hdr->length,
					(unsigned)hdr->srcnode, (unsigned)hdr->destnode);
			break;
		}
	}

	return 0;
}
Пример #29
0
/**
 * Start the loading of @tracee.  This function returns no error since
 * it's either too late to do anything useful (the calling process is
 * already replaced) or the error reported by the kernel
 * (syscall_result < 0) will be propagated as-is.
 */
void translate_execve_exit(Tracee *tracee)
{
	word_t syscall_result;
	int status;

	if (IS_NOTIFICATION_PTRACED_LOAD_DONE(tracee)) {
		/* Be sure not to confuse the ptracer with an
		 * unexpected syscall/returned value.  */
		poke_reg(tracee, SYSARG_RESULT, 0);
		set_sysnum(tracee, PR_execve);

		/* According to most ABIs, all registers have
		 * undefined values at program startup except:
		 *
		 * - the stack pointer
		 * - the instruction pointer
		 * - the rtld_fini pointer
		 * - the state flags
		 */
		poke_reg(tracee, STACK_POINTER, peek_reg(tracee, ORIGINAL, SYSARG_2));
		poke_reg(tracee, INSTR_POINTER, peek_reg(tracee, ORIGINAL, SYSARG_3));
		poke_reg(tracee, RTLD_FINI, 0);
		poke_reg(tracee, STATE_FLAGS, 0);

		/* Restore registers to their current values.  */
		save_current_regs(tracee, ORIGINAL);
		tracee->_regs_were_changed = true;

		/* This is is required to make GDB work correctly
		 * under PRoot, however it deserves to be used
		 * unconditionally.  */
		(void) bind_proc_pid_auxv(tracee);

		/* If the PTRACE_O_TRACEEXEC option is *not* in effect
		 * for the execing tracee, the kernel delivers an
		 * extra SIGTRAP to the tracee after execve(2)
		 * *returns*.  This is an ordinary signal (similar to
		 * one which can be generated by "kill -TRAP"), not a
		 * special kind of ptrace-stop.  Employing
		 * PTRACE_GETSIGINFO for this signal returns si_code
		 * set to 0 (SI_USER).  This signal may be blocked by
		 * signal mask, and thus may be delivered (much)
		 * later. -- man 2 ptrace
		 *
		 * This signal is delayed so far since the program was
		 * not fully loaded yet; GDB would get "invalid
		 * adress" errors otherwise.  */
		if ((tracee->as_ptracee.options & PTRACE_O_TRACEEXEC) == 0)
			kill(tracee->pid, SIGTRAP);

		return;
	}

	syscall_result = peek_reg(tracee, CURRENT, SYSARG_RESULT);
	if ((int) syscall_result < 0)
		return;

	/* Execve happened; commit the new "/proc/self/exe".  */
	if (tracee->new_exe != NULL) {
		(void) talloc_unlink(tracee, tracee->exe);
		tracee->exe = talloc_reference(tracee, tracee->new_exe);
		talloc_set_name_const(tracee->exe, "$exe");
	}

	/* New processes have no heap.  */
	bzero(tracee->heap, sizeof(Heap));

	/* Transfer the load script to the loader.  */
	status = transfer_load_script(tracee);
	if (status < 0)
		note(tracee, ERROR, INTERNAL, "can't transfer load script: %s", strerror(-status));

	return;
}
Пример #30
0
const Object_Class* OBJECT_CLASS_PTR(Object)
{
	static Object_Class the_class = {
		.magic	        = CLASS_MAGIC,
		.name 	        = "Object",
		.super	        = NULL,
		.size	        = sizeof (Object),
		.initializer 	= NULL,
		.finalize	= NULL,
	};
	static const Object the_default_object = { ._.isa = &the_class };
	
	if (the_class.initializer == NULL) {
		_ObjectClass_Lock();
		the_class.initializer = &the_default_object;
		_ObjectClass_Unlock();
	}
	
	return &the_class;
}

const Object_Class* OBJECT_BASE_CLASS_PTR(Object)
{					
	return OBJECT_CLASS_PTR(Object);
}



/*****************************************************************************
 * _Object_check_alloc
 *****************************************************************************/

static const char* const NAME_UNDER_CONSTRUCTION = "under construction";

Object*
_Object_check_alloc (void* talloc_context, const Object_Class* isa)
{
	/*
	 * 1) check if we have a "real" context, or an object already 
	 *    allocated and under construction.
	 */
	if (talloc_get_name (talloc_context) == NAME_UNDER_CONSTRUCTION) {
		return talloc_context; // ---------->
	} 

	/*
	 * 2) Allocate a new object
	 */

	if (isa == NULL) {
		Log_Print (LOG_ERROR, "Object CreateBase NULL isa class");
		return NULL; // ---------->
	}
	
	Object* obj = talloc_named_const (talloc_context, isa->size, 
					  NAME_UNDER_CONSTRUCTION);
	if (obj == NULL) {
		Log_Print (LOG_ERROR, "Object CreateBase Out of Memory");
		return NULL; // ---------->
	}

	// Init fields to default values
	if (isa->initializer)
		memcpy (obj, isa->initializer, isa->size);
	_OBJECT_SET_CLASS (obj, isa);
	
	// Register destructor
	talloc_set_destructor (obj, destroy);
	
	return obj;
}

/*****************************************************************************
 * Object_Create
 *****************************************************************************/

Object* 
Object_Create (void* parent_context, void* unused)
{
	(void) unused;

	Object* self = _Object_check_alloc (parent_context, 
					    OBJECT_BASE_CLASS_PTR (Object));
	
	// Finalize construction
	if (self != NULL) 
		talloc_set_name_const (self, OBJECT_GET_CLASS_NAME (self));
		
	return self;
}