Example #1
0
/*
  move a call from an existing linked list to the specified list. This
  prevents bugs where we forget to remove the call from a previous
  list when moving it.
 */
static void dcesrv_call_set_list(struct dcesrv_call_state *call,
				 enum dcesrv_call_list list)
{
	switch (call->list) {
	case DCESRV_LIST_NONE:
		break;
	case DCESRV_LIST_CALL_LIST:
		DLIST_REMOVE(call->conn->call_list, call);
		break;
	case DCESRV_LIST_FRAGMENTED_CALL_LIST:
		DLIST_REMOVE(call->conn->incoming_fragmented_call_list, call);
		break;
	case DCESRV_LIST_PENDING_CALL_LIST:
		DLIST_REMOVE(call->conn->pending_call_list, call);
		break;
	}
	call->list = list;
	switch (list) {
	case DCESRV_LIST_NONE:
		break;
	case DCESRV_LIST_CALL_LIST:
		DLIST_ADD_END(call->conn->call_list, call);
		break;
	case DCESRV_LIST_FRAGMENTED_CALL_LIST:
		DLIST_ADD_END(call->conn->incoming_fragmented_call_list, call);
		break;
	case DCESRV_LIST_PENDING_CALL_LIST:
		DLIST_ADD_END(call->conn->pending_call_list, call);
		break;
	}
}
Example #2
0
/*
  a client has asked to register a unique name that someone else owns. We
  need to ask each of the current owners if they still want it. If they do
  then reject the registration, otherwise allow it
*/
static void wins_register_wack(struct nbt_name_socket *nbtsock, 
			       struct nbt_name_packet *packet, 
			       struct winsdb_record *rec,
			       struct socket_address *src,
			       enum wrepl_name_type new_type)
{
	struct nbtd_interface *iface = talloc_get_type(nbtsock->incoming.private_data,
						       struct nbtd_interface);
	struct wins_server *winssrv = iface->nbtsrv->winssrv;
	struct nbtd_wins_wack_state *s;
	struct composite_context *c_req;
	uint32_t ttl;

	s = talloc_zero(nbtsock, struct nbtd_wins_wack_state);
	if (s == NULL) goto failed;

	/* package up the state variables for this wack request */
	s->winssrv		= winssrv;
	s->nbtsock		= nbtsock;
	s->iface		= iface;
	s->request_packet	= talloc_steal(s, packet);
	s->rec			= talloc_steal(s, rec);
	s->reg_address		= packet->additional[0].rdata.netbios.addresses[0].ipaddr;
	s->new_type		= new_type;
	s->src		        = socket_address_copy(s, src);
	if (s->src == NULL) goto failed;

	s->io.in.nbtd_server	= iface->nbtsrv;
	s->io.in.nbt_port       = lpcfg_nbt_port(iface->nbtsrv->task->lp_ctx);
	s->io.in.event_ctx	= iface->nbtsrv->task->event_ctx;
	s->io.in.name		= rec->name;
	s->io.in.num_addresses	= winsdb_addr_list_length(rec->addresses);
	s->io.in.addresses	= winsdb_addr_string_list(s, rec->addresses);
	if (s->io.in.addresses == NULL) goto failed;

	DLIST_ADD_END(iface->wack_queue, s);

	talloc_set_destructor(s, nbtd_wins_wack_state_destructor);

	/*
	 * send a WACK to the client, specifying the maximum time it could
         * take to check with the owner, plus some slack
	 */
	ttl = 5 + 4 * winsdb_addr_list_length(rec->addresses);
	nbtd_wack_reply(nbtsock, packet, src, ttl);

	/*
	 * send the challenge to the old addresses
	 */
	c_req = wins_challenge_send(s, &s->io);
	if (c_req == NULL) goto failed;

	c_req->async.fn			= wack_wins_challenge_handler;
	c_req->async.private_data	= s;
	return;

failed:
	talloc_free(s);
	nbtd_name_registration_reply(nbtsock, packet, src, NBT_RCODE_SVR);
}
/**
 * Search an entry as specified via file name. If found, moved entry
 * to the end of the list, too
 * @param fname file name
 * @return a pointer to the found entry or NULL
 *
*/
struct lrufiles_struct *lrufiles_search(pstring fname) {
        struct lrufiles_struct *curr, *tmp = NULL;

	DEBUG(10, ("search for '%s' in lrufiles\n", fname));
        /* search backwards */
        curr = LrufilesEnd;
        while ( curr != NULL ) {
                if ( StrCaseCmp(fname, curr->fname) == 0 ) {
			DEBUG(10, ("file '%s' matched\n", fname));
                        /* match ... */
                        /* move to end of list */
                        DLIST_REMOVE(Lrufiles, curr);
			#if (SMB_VFS_INTERFACE_VERSION >= 21)
			 DLIST_ADD_END(Lrufiles, curr, struct lrufiles_struct *);
			#else
                         DLIST_ADD_END(Lrufiles, curr, tmp);
			#endif
                        LrufilesEnd = curr;
                        /* return it */
                        return curr;
                }
                curr = curr->prev;
        }

        /* not found */
	DEBUG(10, ("file '%s' not matched\n", fname));
        return NULL;
}
Example #4
0
static NTSTATUS make_auth_context_text_list(struct auth_context **auth_context, char **text_list) 
{
	auth_methods *list = NULL;
	auth_methods *t = NULL;
	auth_methods *tmp;
	NTSTATUS nt_status;

	if (!text_list) {
		DEBUG(2,("make_auth_context_text_list: No auth method list!?\n"));
		return NT_STATUS_UNSUCCESSFUL;
	}
	
	if (!NT_STATUS_IS_OK(nt_status = make_auth_context(auth_context)))
		return nt_status;

	for (;*text_list; text_list++) { 
		if (load_auth_module(*auth_context, *text_list, &t)) {
		    DLIST_ADD_END(list, t, tmp);
		}
	}
	
	(*auth_context)->auth_method_list = list;
	
	return nt_status;
}
Example #5
0
/*
  queue a datagram for send
*/
NTSTATUS nbt_dgram_send(struct nbt_dgram_socket *dgmsock,
			struct nbt_dgram_packet *packet,
			struct socket_address *dest)
{
	struct nbt_dgram_request *req;
	NTSTATUS status = NT_STATUS_NO_MEMORY;
	enum ndr_err_code ndr_err;

	req = talloc(dgmsock, struct nbt_dgram_request);
	if (req == NULL) goto failed;

	req->dest = dest;
	if (talloc_reference(req, dest) == NULL) goto failed;

	ndr_err = ndr_push_struct_blob(&req->encoded, req, packet,
				      (ndr_push_flags_fn_t)ndr_push_nbt_dgram_packet);
	if (!NDR_ERR_CODE_IS_SUCCESS(ndr_err)) {
		status = ndr_map_error2ntstatus(ndr_err);
		goto failed;
	}

	DLIST_ADD_END(dgmsock->send_queue, req);

	TEVENT_FD_WRITEABLE(dgmsock->fde);

	return NT_STATUS_OK;

failed:
	talloc_free(req);
	return status;
}
Example #6
0
/*
 * Lock record / db depending on type
 */
static struct lock_request *ctdb_lock_internal(struct ctdb_context *ctdb,
					       struct ctdb_db_context *ctdb_db,
					       TDB_DATA key,
					       uint32_t priority,
					       void (*callback)(void *, bool),
					       void *private_data,
					       enum lock_type type,
					       bool auto_mark)
{
	struct lock_context *lock_ctx = NULL;
	struct lock_request *request;

	if (callback == NULL) {
		DEBUG(DEBUG_WARNING, ("No callback function specified, not locking\n"));
		return NULL;
	}

#if 0
	/* Disable this optimization to ensure first-in-first-out fair
	 * scheduling of lock requests */

	/* get a context for this key - search only the pending contexts,
	 * current contexts might in the middle of processing callbacks */
	lock_ctx = find_lock_context(ctdb->lock_pending, ctdb_db, key, priority, type);
#endif

	/* No existing context, create one */
	if (lock_ctx == NULL) {
		lock_ctx = talloc_zero(ctdb, struct lock_context);
		if (lock_ctx == NULL) {
			DEBUG(DEBUG_ERR, ("Failed to create a new lock context\n"));
			return NULL;
		}

		lock_ctx->type = type;
		lock_ctx->ctdb = ctdb;
		lock_ctx->ctdb_db = ctdb_db;
		lock_ctx->key.dsize = key.dsize;
		if (key.dsize > 0) {
			lock_ctx->key.dptr = talloc_memdup(lock_ctx, key.dptr, key.dsize);
		} else {
			lock_ctx->key.dptr = NULL;
		}
		lock_ctx->priority = priority;
		lock_ctx->auto_mark = auto_mark;

		lock_ctx->child = -1;
		lock_ctx->block_child = -1;

		DLIST_ADD_END(ctdb->lock_pending, lock_ctx, NULL);
		ctdb->lock_num_pending++;
		CTDB_INCREMENT_STAT(ctdb, locks.num_pending);
		if (ctdb_db) {
			CTDB_INCREMENT_DB_STAT(ctdb_db, locks.num_pending);
		}

		/* Start the timer when we activate the context */
		lock_ctx->start_time = timeval_current();
	}
/** 
 * Adds a new entry, or if the entry already exists, mtime and infected values
 * are updated
 * @param fname the file name
 * @param mtime time the file was last modified
 * @param infected marks a file as infected or not infected
 * @return returns a pointer of the new entry, the updated entry or NULL
 *	   if no memory could be allocated
 *
*/
struct lrufiles_struct *lrufiles_add(pstring fname, time_t mtime, bool infected) {
	struct lrufiles_struct *new_entry, *tmp, *found = NULL;

	/* check if lru file access was disabled by setting the corresponding
	   value in the configuration file to zero (or below zero) */
	if ( lrufiles_max_entries <= 0 ) {
		DEBUG(1, ("lru files feature is disabled, do nothing\n"));
		/* do nothing, simply return NULL */
		return NULL;
	}
	DEBUG(10, ("file '%s' should be added\n", fname));
	/* check if file has already been added */
	found = lrufiles_search(fname);
	if ( found != NULL ) {
		/* has already been added, update mtime and infected only */
		DEBUG(10, ("file '%s' in list, update mtime and infected\n", fname));
		found->mtime = mtime;
		found->infected = infected;
		/* FIXME hm, should we updated it or not?! */
		/* found->time_added = time(NULL); */
		return found;
	} else {
		DEBUG(10, ("alloc space for file entry '%s'\n", fname));
		new_entry = (struct lrufiles_struct *)malloc(sizeof(*new_entry));
		if (!new_entry) return NULL;

		ZERO_STRUCTP(new_entry);

		pstrcpy(new_entry->fname, fname);
		new_entry->mtime = mtime;
		new_entry->infected = infected;
		new_entry->time_added = time(NULL);

		/* reached maximum? */
		if ( lrufiles_count == lrufiles_max_entries ) {
			DEBUG(10, ("lru maximum reached '%d'\n", lrufiles_count));
			/* remove the first one - it really removes only the first one */
			tmp = Lrufiles;
			DEBUG(10, ("removing first entry..."));
			lrufiles_delete_p(tmp);
		}
		
		DEBUG(10, ("adding new entry to list...\n"));
		#if (SMB_VFS_INTERFACE_VERSION >= 21)
 		 DLIST_ADD_END(Lrufiles, new_entry, struct lrufiles_struct *);
		#else
		 DLIST_ADD_END(Lrufiles, new_entry, tmp);
		#endif
		LrufilesEnd = new_entry;
		lrufiles_count++;
		DEBUG(10, ("entry '%s' added, count '%d'\n", fname, lrufiles_count));

		return new_entry;
	}
}
Example #8
0
/**
 * Add a child testsuite to a testsuite.
 */
bool torture_suite_add_suite(struct torture_suite *suite,
                             struct torture_suite *child)
{
    if (child == NULL)
        return false;

    DLIST_ADD_END(suite->children, child);

    /* FIXME: Check for duplicates and return false if the
     * added suite already exists as a child */

    return true;
}
Example #9
0
int iscsi_queue_pdu(struct iscsi_context *iscsi, struct iscsi_pdu *pdu)
{
	if (iscsi == NULL) {
		printf("trying to queue to NULL context\n");
		return -1;
	}
	if (pdu == NULL) {
		printf("trying to queue NULL pdu\n");
		return -2;
	}
	DLIST_ADD_END(iscsi->outqueue, pdu, NULL);

	return 0;
}
Example #10
0
/**
 * Add a new testcase
 */
bool torture_suite_init_tcase(struct torture_suite *suite,
                              struct torture_tcase *tcase,
                              const char *name)
{
    tcase->name = talloc_strdup(tcase, name);
    tcase->description = NULL;
    tcase->setup = NULL;
    tcase->teardown = NULL;
    tcase->fixture_persistent = true;
    tcase->tests = NULL;

    DLIST_ADD_END(suite->testcases, tcase);

    return true;
}
Example #11
0
/*
  return a dcerpc fault
*/
NTSTATUS dcesrv_fault(struct dcesrv_call_state *call, uint32_t fault_code)
{
	struct ncacn_packet pkt;
	struct data_blob_list_item *rep;
	uint8_t zeros[4];
	NTSTATUS status;

	/* setup a bind_ack */
	dcesrv_init_hdr(&pkt, lpcfg_rpc_big_endian(call->conn->dce_ctx->lp_ctx));
	pkt.auth_length = 0;
	pkt.call_id = call->pkt.call_id;
	pkt.ptype = DCERPC_PKT_FAULT;
	pkt.pfc_flags = DCERPC_PFC_FLAG_FIRST | DCERPC_PFC_FLAG_LAST;
	pkt.u.fault.alloc_hint = 0;
	pkt.u.fault.context_id = 0;
	pkt.u.fault.cancel_count = 0;
	pkt.u.fault.status = fault_code;

	ZERO_STRUCT(zeros);
	pkt.u.fault._pad = data_blob_const(zeros, sizeof(zeros));

	rep = talloc(call, struct data_blob_list_item);
	if (!rep) {
		return NT_STATUS_NO_MEMORY;
	}

	status = ncacn_push_auth(&rep->blob, call, &pkt, NULL);
	if (!NT_STATUS_IS_OK(status)) {
		return status;
	}

	dcerpc_set_frag_length(&rep->blob, rep->blob.length);

	DLIST_ADD_END(call->replies, rep);
	dcesrv_call_set_list(call, DCESRV_LIST_CALL_LIST);

	if (call->conn->call_list && call->conn->call_list->replies) {
		if (call->conn->transport.report_output_data) {
			call->conn->transport.report_output_data(call->conn);
		}
	}

	return NT_STATUS_OK;
}
Example #12
0
struct torture_test *torture_tcase_add_simple_test(struct torture_tcase *tcase,
        const char *name,
        bool (*run) (struct torture_context *test, void *tcase_data))
{
    struct torture_test *test;

    test = talloc(tcase, struct torture_test);

    test->name = talloc_strdup(test, name);
    test->description = NULL;
    test->run = wrap_test_with_simple_test;
    test->fn = run;
    test->data = NULL;
    test->dangerous = false;

    DLIST_ADD_END(tcase->tests, test);

    return test;
}
Example #13
0
static BOOL push_queued_message(char *buf, int msg_len,
				struct timeval request_time,
				struct timeval end_time,
				char *private_data, size_t private_len)
{
	struct pending_message_list *tmp_msg;
	struct pending_message_list *msg;

	msg = TALLOC_ZERO_P(NULL, struct pending_message_list);

	if(msg == NULL) {
		DEBUG(0,("push_message: malloc fail (1)\n"));
		return False;
	}

	msg->buf = data_blob_talloc(msg, buf, msg_len);
	if(msg->buf.data == NULL) {
		DEBUG(0,("push_message: malloc fail (2)\n"));
		TALLOC_FREE(msg);
		return False;
	}

	msg->request_time = request_time;
	msg->end_time = end_time;

	if (private_data) {
		msg->private_data = data_blob_talloc(msg, private_data,
						     private_len);
		if (msg->private_data.data == NULL) {
			DEBUG(0,("push_message: malloc fail (3)\n"));
			TALLOC_FREE(msg);
			return False;
		}
	}

	DLIST_ADD_END(deferred_open_queue, msg, tmp_msg);

	DEBUG(10,("push_message: pushed message length %u on "
		  "deferred_open_queue\n", (unsigned int)msg_len));

	return True;
}
Example #14
0
struct torture_tcase *torture_suite_add_simple_test(
    struct torture_suite *suite,
    const char *name,
    bool (*run) (struct torture_context *test))
{
    struct torture_test *test;
    struct torture_tcase *tcase;

    tcase = torture_suite_add_tcase(suite, name);

    test = talloc(tcase, struct torture_test);

    test->name = talloc_strdup(test, name);
    test->description = NULL;
    test->run = wrap_simple_test;
    test->fn = run;
    test->dangerous = false;

    DLIST_ADD_END(tcase->tests, test);

    return tcase;
}
Example #15
0
static int iscsi_write_to_socket(struct iscsi_context *iscsi)
{
	ssize_t count;

	if (iscsi == NULL) {
		printf("trying to write to socket for NULL context\n");
		return -1;
	}
	if (iscsi->fd == -1) {
		printf("trying to write but not connected\n");
		return -2;
	}

	while (iscsi->outqueue != NULL) {
		ssize_t total;

		total = iscsi->outqueue->outdata.size;
		total = (total +3) & 0xfffffffc;

		count = write(iscsi->fd, iscsi->outqueue->outdata.data + iscsi->outqueue->written, total - iscsi->outqueue->written);
		if (count == -1) {
			if (errno == EAGAIN || errno == EWOULDBLOCK) {
				printf("socket would block, return from write to socket\n");
				return 0;
			}
			printf("Error when writing to socket :%d\n", errno);
			return -3;
		}

		iscsi->outqueue->written += count;
		if (iscsi->outqueue->written == total) {
			struct iscsi_pdu *pdu = iscsi->outqueue;

	       	    	DLIST_REMOVE(iscsi->outqueue, pdu);
			DLIST_ADD_END(iscsi->waitpdu, pdu, NULL);
		}
	}
	return 0;
}
Example #16
0
File: auth.c Project: encukou/samba
static NTSTATUS make_auth_context_text_list(TALLOC_CTX *mem_ctx,
					    struct auth_context **auth_context,
					    char **text_list)
{
	auth_methods *list = NULL;
	auth_methods *t, *method = NULL;
	NTSTATUS nt_status;

	if (!text_list) {
		DEBUG(2,("make_auth_context_text_list: No auth method list!?\n"));
		return NT_STATUS_UNSUCCESSFUL;
	}

	nt_status = make_auth_context(mem_ctx, auth_context);

	if (!NT_STATUS_IS_OK(nt_status)) {
		return nt_status;
	}

	for (;*text_list; text_list++) { 
		if (load_auth_module(*auth_context, *text_list, &t)) {
		    DLIST_ADD_END(list, t);
		}
	}

	(*auth_context)->auth_method_list = list;

	/* Look for the first module to provide a prepare_gensec and
	 * make_auth4_context hook, and set that if provided */
	for (method = (*auth_context)->auth_method_list; method; method = method->next) {
		if (method->prepare_gensec && method->make_auth4_context) {
			(*auth_context)->prepare_gensec = method->prepare_gensec;
			(*auth_context)->make_auth4_context = method->make_auth4_context;
			break;
		}
	}
	return NT_STATUS_OK;
}
Example #17
0
/****************************************************************************
add an interface to the linked list of interfaces
****************************************************************************/
static void add_interface(TALLOC_CTX *mem_ctx, const struct iface_struct *ifs, struct interface **interfaces,
                          bool enable_ipv6)
{
    char addr[INET6_ADDRSTRLEN];
    struct interface *iface;

    if (iface_list_find(*interfaces, (const struct sockaddr *)&ifs->ip, false)) {
        DEBUG(3,("add_interface: not adding duplicate interface %s\n",
                 print_sockaddr(addr, sizeof(addr), &ifs->ip) ));
        return;
    }

    if (!(ifs->flags & (IFF_BROADCAST|IFF_LOOPBACK))) {
        DEBUG(3,("not adding non-broadcast interface %s\n",
                 ifs->name ));
        return;
    }

    if (!enable_ipv6 && ifs->ip.ss_family != AF_INET) {
        return;
    }

    iface = talloc(*interfaces == NULL ? mem_ctx : *interfaces, struct interface);
    if (iface == NULL)
        return;

    ZERO_STRUCTPN(iface);

    iface->name = talloc_strdup(iface, ifs->name);
    if (!iface->name) {
        SAFE_FREE(iface);
        return;
    }
    iface->flags = ifs->flags;
    iface->ip = ifs->ip;
    iface->netmask = ifs->netmask;
    iface->bcast = ifs->bcast;

    /* keep string versions too, to avoid people tripping over the implied
       static in inet_ntoa() */
    print_sockaddr(addr, sizeof(addr), &iface->ip);
    DEBUG(4,("added interface %s ip=%s ",
             iface->name, addr));
    iface->ip_s = talloc_strdup(iface, addr);

    print_sockaddr(addr, sizeof(addr),
                   &iface->bcast);
    DEBUG(4,("bcast=%s ", addr));
    iface->bcast_s = talloc_strdup(iface, addr);

    print_sockaddr(addr, sizeof(addr),
                   &iface->netmask);
    DEBUG(4,("netmask=%s\n", addr));
    iface->nmask_s = talloc_strdup(iface, addr);

    /*
       this needs to be a ADD_END, as some tests (such as the
       spoolss notify test) depend on the interfaces ordering
    */
    DLIST_ADD_END(*interfaces, iface, NULL);
}
Example #18
0
/* Add a trusted domain out of a trusted domain cache
   entry
*/
static struct winbindd_domain *
add_trusted_domain_from_tdc(const struct winbindd_tdc_domain *tdc)
{
	struct winbindd_domain *domain;
	const char *alternative_name = NULL;
	const char **ignored_domains, **dom;
	int role = lp_server_role();
	const char *domain_name = tdc->domain_name;
	const struct dom_sid *sid = &tdc->sid;

	if (is_null_sid(sid)) {
		sid = NULL;
	}

	ignored_domains = lp_parm_string_list(-1, "winbind", "ignore domains", NULL);
	for (dom=ignored_domains; dom && *dom; dom++) {
		if (gen_fnmatch(*dom, domain_name) == 0) {
			DEBUG(2,("Ignoring domain '%s'\n", domain_name));
			return NULL;
		}
	}

	/* use alt_name if available to allow DNS lookups */

	if (tdc->dns_name && *tdc->dns_name) {
		alternative_name = tdc->dns_name;
	}

	/* We can't call domain_list() as this function is called from
	   init_domain_list() and we'll get stuck in a loop. */
	for (domain = _domain_list; domain; domain = domain->next) {
		if (strequal(domain_name, domain->name) ||
		    strequal(domain_name, domain->alt_name))
		{
			break;
		}

		if (alternative_name) {
			if (strequal(alternative_name, domain->name) ||
			    strequal(alternative_name, domain->alt_name))
			{
				break;
			}
		}

		if (sid != NULL) {
			if (dom_sid_equal(sid, &domain->sid)) {
				break;
			}
		}
	}

	if (domain != NULL) {
		/*
		 * We found a match on domain->name or
		 * domain->alt_name. Possibly update the SID
		 * if the stored SID was the NULL SID
		 * and return the matching entry.
		 */
		if ((sid != NULL)
		    && dom_sid_equal(&domain->sid, &global_sid_NULL)) {
			sid_copy( &domain->sid, sid );
		}
		return domain;
	}

	/* Create new domain entry */
	domain = talloc_zero(NULL, struct winbindd_domain);
	if (domain == NULL) {
		return NULL;
	}

	domain->children = talloc_zero_array(domain,
					     struct winbindd_child,
					     lp_winbind_max_domain_connections());
	if (domain->children == NULL) {
		TALLOC_FREE(domain);
		return NULL;
	}

	domain->name = talloc_strdup(domain, domain_name);
	if (domain->name == NULL) {
		TALLOC_FREE(domain);
		return NULL;
	}

	if (alternative_name) {
		domain->alt_name = talloc_strdup(domain, alternative_name);
		if (domain->alt_name == NULL) {
			TALLOC_FREE(domain);
			return NULL;
		}
	}

	domain->backend = NULL;
	domain->internal = is_internal_domain(sid);
	domain->sequence_number = DOM_SEQUENCE_NONE;
	domain->last_seq_check = 0;
	domain->initialized = false;
	domain->online = is_internal_domain(sid);
	domain->check_online_timeout = 0;
	domain->dc_probe_pid = (pid_t)-1;
	if (sid != NULL) {
		sid_copy(&domain->sid, sid);
	}
	domain->domain_flags = tdc->trust_flags;
	domain->domain_type = tdc->trust_type;
	domain->domain_trust_attribs = tdc->trust_attribs;

	/* Is this our primary domain ? */
	if (strequal(domain_name, get_global_sam_name()) &&
			(role != ROLE_DOMAIN_MEMBER)) {
		domain->primary = true;
	} else if (strequal(domain_name, lp_workgroup()) &&
			(role == ROLE_DOMAIN_MEMBER)) {
		domain->primary = true;
	}

	if (domain->primary) {
		if (role == ROLE_ACTIVE_DIRECTORY_DC) {
			domain->active_directory = true;
		}
		if (lp_security() == SEC_ADS) {
			domain->active_directory = true;
		}
	} else if (!domain->internal) {
		if (domain->domain_type == LSA_TRUST_TYPE_UPLEVEL) {
			domain->active_directory = true;
		}
	}

	/* Link to domain list */
	DLIST_ADD_END(_domain_list, domain);

	wcache_tdc_add_domain( domain );

	setup_domain_child(domain);

	DEBUG(2,
	      ("Added domain %s %s %s\n", domain->name, domain->alt_name,
	       !is_null_sid(&domain->sid) ? sid_string_dbg(&domain->sid) : ""));

	return domain;
}
Example #19
0
static bool nb_do_createx(struct ftable *f,
			  const char *fname,
			  unsigned int create_options,
			  unsigned int create_disposition,
			  int handle,
			  NTSTATUS status,
			  bool retry)
{
	union smb_open io;	
	uint32_t desired_access;
	NTSTATUS ret;
	TALLOC_CTX *mem_ctx;
	unsigned int flags = 0;

	mem_ctx = talloc_init("raw_open");

	if (create_options & NTCREATEX_OPTIONS_DIRECTORY) {
		desired_access = SEC_FILE_READ_DATA;
	} else {
		desired_access = 
			SEC_FILE_READ_DATA | 
			SEC_FILE_WRITE_DATA |
			SEC_FILE_READ_ATTRIBUTE |
			SEC_FILE_WRITE_ATTRIBUTE;
		flags = NTCREATEX_FLAGS_EXTENDED |
			NTCREATEX_FLAGS_REQUEST_OPLOCK | 
			NTCREATEX_FLAGS_REQUEST_BATCH_OPLOCK;
	}

	io.ntcreatex.level = RAW_OPEN_NTCREATEX;
	io.ntcreatex.in.flags = flags;
	io.ntcreatex.in.root_fid.fnum = 0;
	io.ntcreatex.in.access_mask = desired_access;
	io.ntcreatex.in.file_attr = 0;
	io.ntcreatex.in.alloc_size = 0;
	io.ntcreatex.in.share_access = NTCREATEX_SHARE_ACCESS_READ|NTCREATEX_SHARE_ACCESS_WRITE;
	io.ntcreatex.in.open_disposition = create_disposition;
	io.ntcreatex.in.create_options = create_options;
	io.ntcreatex.in.impersonation = 0;
	io.ntcreatex.in.security_flags = 0;
	io.ntcreatex.in.fname = fname;

	if (retry) {
		/* Reopening after a disconnect. */
		io.ntcreatex.in.open_disposition = NTCREATEX_DISP_OPEN_IF;
	} else
	if (f != NULL &&
	    f->cp.create_disposition == NTCREATEX_DISP_CREATE &&
	    NT_STATUS_IS_OK(status))
	{
		/* Reopening after nb_createx() error. */
		io.ntcreatex.in.open_disposition = NTCREATEX_DISP_OPEN_IF;
	}

	ret = smb_raw_open(c->tree, mem_ctx, &io);

	talloc_free(mem_ctx);

	if (!check_status("NTCreateX", status, ret))
		return false;

	if (!NT_STATUS_IS_OK(ret))
		return true;

	if (f == NULL) {
		f = talloc (NULL, struct ftable);
		f->locks = NULL;
		nb_set_createx_params(f, fname, create_options, create_disposition, handle);
		DLIST_ADD_END(ftable, f);
	}
Example #20
0
static void send_spoolss_notify2_msg(struct tevent_context *ev,
				     struct messaging_context *msg_ctx,
				     SPOOLSS_NOTIFY_MSG *msg)
{
	struct notify_queue *pnqueue, *tmp_ptr;

	/*
	 * Ensure we only have one job total_bytes and job total_pages for
	 * each job. There is no point in sending multiple messages that match
	 * as they will just cause flickering updates in the client.
	 */

	if ((num_messages < 100) && (msg->type == JOB_NOTIFY_TYPE) 
		&& (msg->field == JOB_NOTIFY_FIELD_TOTAL_BYTES
		    || msg->field == JOB_NOTIFY_FIELD_TOTAL_PAGES ))
	{

		for (tmp_ptr = notify_queue_head; tmp_ptr; tmp_ptr = tmp_ptr->next) 
		{
			if (tmp_ptr->msg->type == msg->type &&
					tmp_ptr->msg->field == msg->field &&
					tmp_ptr->msg->id == msg->id &&
					tmp_ptr->msg->flags == msg->flags &&
					strequal(tmp_ptr->msg->printer, msg->printer)) {

				DEBUG(5,("send_spoolss_notify2_msg: replacing message 0x%02x/0x%02x for "
					 "printer %s in notify_queue\n", msg->type, msg->field, msg->printer));

				tmp_ptr->msg = msg;
				return;
			}
		}
	}

	/* Store the message on the pending queue. */

	pnqueue = talloc(send_ctx, struct notify_queue);
	if (!pnqueue) {
		DEBUG(0,("send_spoolss_notify2_msg: Out of memory.\n"));
		return;
	}

	/* allocate a new msg structure and copy the fields */
	
	if ( !(pnqueue->msg = talloc(send_ctx, SPOOLSS_NOTIFY_MSG)) ) {
		DEBUG(0,("send_spoolss_notify2_msg: talloc() of size [%lu] failed!\n", 
			(unsigned long)sizeof(SPOOLSS_NOTIFY_MSG)));
		return;
	}
	copy_notify2_msg(pnqueue->msg, msg);
	GetTimeOfDay(&pnqueue->tv);
	pnqueue->buf = NULL;
	pnqueue->buflen = 0;

	DEBUG(5, ("send_spoolss_notify2_msg: appending message 0x%02x/0x%02x for printer %s \
to notify_queue_head\n", msg->type, msg->field, msg->printer));

	/*
	 * Note we add to the end of the list to ensure
	 * the messages are sent in the order they were received. JRA.
	 */

	DLIST_ADD_END(notify_queue_head, pnqueue);
	num_messages++;

	if ((notify_event == NULL) && (ev != NULL)) {
		/* Add an event for 1 second's time to send this queue. */
		notify_event = tevent_add_timer(
			ev, NULL, timeval_current_ofs(1,0),
			print_notify_event_send_messages, msg_ctx);
	}

}
Example #21
0
static struct tevent_queue_entry *tevent_queue_add_internal(
					struct tevent_queue *queue,
					struct tevent_context *ev,
					struct tevent_req *req,
					tevent_queue_trigger_fn_t trigger,
					void *private_data,
					bool allow_direct)
{
	struct tevent_queue_entry *e;

	e = talloc_zero(req, struct tevent_queue_entry);
	if (e == NULL) {
		return NULL;
	}

	e->queue = queue;
	e->req = req;
	e->ev = ev;
	e->trigger = trigger;
	e->private_data = private_data;

	/*
	 * if there is no trigger, it is just a blocker
	 */
	if (trigger == NULL) {
		e->triggered = true;
	}

	if (queue->length > 0) {
		/*
		 * if there are already entries in the
		 * queue do not optimize.
		 */
		allow_direct = false;
	}

	if (req->async.fn != NULL) {
		/*
		 * If the caller wants to optimize for the
		 * empty queue case, call the trigger only
		 * if there is no callback defined for the
		 * request yet.
		 */
		allow_direct = false;
	}

	DLIST_ADD_END(queue->list, e);
	queue->length++;
	talloc_set_destructor(e, tevent_queue_entry_destructor);

	if (!queue->running) {
		return e;
	}

	if (queue->list->triggered) {
		return e;
	}

	/*
	 * If allowed we directly call the trigger
	 * avoiding possible delays caused by
	 * an immediate event.
	 */
	if (allow_direct) {
		queue->list->triggered = true;
		queue->list->trigger(queue->list->req,
				     queue->list->private_data);
		return e;
	}

	tevent_schedule_immediate(queue->immediate,
				  queue->list->ev,
				  tevent_queue_immediate_trigger,
				  queue);

	return e;
}
Example #22
0
BOOL push_blocking_lock_request( char *inbuf, int length, int lock_timeout,
		int lock_num, uint16 lock_pid, SMB_BIG_UINT offset, SMB_BIG_UINT count)
{
	static BOOL set_lock_msg;
	blocking_lock_record *blr, *tmp;
	BOOL my_lock_ctx = False;
	NTSTATUS status;

	if(in_chained_smb() ) {
		DEBUG(0,("push_blocking_lock_request: cannot queue a chained request (currently).\n"));
		return False;
	}

	/*
	 * Now queue an entry on the blocking lock queue. We setup
	 * the expiration time here.
	 */

	if((blr = SMB_MALLOC_P(blocking_lock_record)) == NULL) {
		DEBUG(0,("push_blocking_lock_request: Malloc fail !\n" ));
		return False;
	}

	if((blr->inbuf = (char *)SMB_MALLOC(length)) == NULL) {
		DEBUG(0,("push_blocking_lock_request: Malloc fail (2)!\n" ));
		SAFE_FREE(blr);
		return False;
	}

	blr->com_type = CVAL(inbuf,smb_com);
	blr->fsp = get_fsp_from_pkt(inbuf);
	blr->expire_time = (lock_timeout == -1) ? (time_t)-1 : time(NULL) + (time_t)lock_timeout;
	blr->lock_num = lock_num;
	blr->lock_pid = lock_pid;
	blr->offset = offset;
	blr->count = count;
	memcpy(blr->inbuf, inbuf, length);
	blr->length = length;

	/* Add a pending lock record for this. */
	status = brl_lock(blr->fsp->dev, blr->fsp->inode, blr->fsp->fnum,
			lock_pid, sys_getpid(), blr->fsp->conn->cnum,
			offset, count, PENDING_LOCK, &my_lock_ctx);

	if (!NT_STATUS_IS_OK(status)) {
		DEBUG(0,("push_blocking_lock_request: failed to add PENDING_LOCK record.\n"));
		free_blocking_lock_record(blr);
		return False;
	}

	DLIST_ADD_END(blocking_lock_queue, blr, tmp);

	/* Ensure we'll receive messages when this is unlocked. */
	if (!set_lock_msg) {
		message_register(MSG_SMB_UNLOCK, received_unlock_msg);
		set_lock_msg = True;
	}

	DEBUG(3,("push_blocking_lock_request: lock request length=%d blocked with expiry time %d (+%d) \
for fnum = %d, name = %s\n", length, (int)blr->expire_time, lock_timeout,
		blr->fsp->fnum, blr->fsp->fsp_name ));

	/* Push the MID of this packet on the signing queue. */
	srv_defer_sign_response(SVAL(inbuf,smb_mid));

	return True;
}
Example #23
0
static struct aio_open_private_data *create_private_open_data(const files_struct *fsp,
					int flags,
					mode_t mode)
{
	struct aio_open_private_data *opd = talloc_zero(NULL,
					struct aio_open_private_data);
	const char *fname = NULL;

	if (!opd) {
		return NULL;
	}

	opd->jobid = aio_pthread_open_jobid++;
	opd->dir_fd = -1;
	opd->ret_fd = -1;
	opd->ret_errno = EINPROGRESS;
	opd->flags = flags;
	opd->mode = mode;
	opd->mid = fsp->mid;
	opd->in_progress = true;
	opd->sconn = fsp->conn->sconn;
	opd->initial_allocation_size = fsp->initial_allocation_size;

	/* Copy our current credentials. */
	opd->ux_tok = copy_unix_token(opd, get_current_utok(fsp->conn));
	if (opd->ux_tok == NULL) {
		TALLOC_FREE(opd);
		return NULL;
	}

	/*
	 * Copy the parent directory name and the
	 * relative path within it.
	 */
	if (parent_dirname(opd,
			fsp->fsp_name->base_name,
			&opd->dname,
			&fname) == false) {
		TALLOC_FREE(opd);
		return NULL;
	}
	opd->fname = talloc_strdup(opd, fname);
	if (opd->fname == NULL) {
		TALLOC_FREE(opd);
		return NULL;
	}

#if defined(O_DIRECTORY)
	opd->dir_fd = open(opd->dname, O_RDONLY|O_DIRECTORY);
#else
	opd->dir_fd = open(opd->dname, O_RDONLY);
#endif
	if (opd->dir_fd == -1) {
		TALLOC_FREE(opd);
		return NULL;
	}

	talloc_set_destructor(opd, opd_destructor);
	DLIST_ADD_END(open_pd_list, opd);
	return opd;
}
Example #24
0
_PUBLIC_ NTSTATUS dcesrv_reply(struct dcesrv_call_state *call)
{
	struct ndr_push *push;
	NTSTATUS status;
	DATA_BLOB stub;
	uint32_t total_length, chunk_size;
	struct dcesrv_connection_context *context = call->context;
	size_t sig_size = 0;

	/* call the reply function */
	status = context->iface->reply(call, call, call->r);
	if (!NT_STATUS_IS_OK(status)) {
		return dcesrv_fault(call, call->fault_code);
	}

	/* form the reply NDR */
	push = ndr_push_init_ctx(call);
	NT_STATUS_HAVE_NO_MEMORY(push);

	/* carry over the pointer count to the reply in case we are
	   using full pointer. See NDR specification for full
	   pointers */
	push->ptr_count = call->ndr_pull->ptr_count;

	if (lpcfg_rpc_big_endian(call->conn->dce_ctx->lp_ctx)) {
		push->flags |= LIBNDR_FLAG_BIGENDIAN;
	}

	status = context->iface->ndr_push(call, call, push, call->r);
	if (!NT_STATUS_IS_OK(status)) {
		return dcesrv_fault(call, call->fault_code);
	}

	stub = ndr_push_blob(push);

	total_length = stub.length;

	/* we can write a full max_recv_frag size, minus the dcerpc
	   request header size */
	chunk_size = call->conn->cli_max_recv_frag;
	chunk_size -= DCERPC_REQUEST_LENGTH;
	if (call->conn->auth_state.auth_info &&
	    call->conn->auth_state.gensec_security) {
		size_t max_payload = chunk_size;

		max_payload -= DCERPC_AUTH_TRAILER_LENGTH;
		max_payload -= (max_payload % DCERPC_AUTH_PAD_ALIGNMENT);

		sig_size = gensec_sig_size(call->conn->auth_state.gensec_security,
					   max_payload);
		if (sig_size) {
			chunk_size -= DCERPC_AUTH_TRAILER_LENGTH;
			chunk_size -= sig_size;
		}
	}
	chunk_size -= (chunk_size % DCERPC_AUTH_PAD_ALIGNMENT);

	do {
		uint32_t length;
		struct data_blob_list_item *rep;
		struct ncacn_packet pkt;

		rep = talloc(call, struct data_blob_list_item);
		NT_STATUS_HAVE_NO_MEMORY(rep);

		length = MIN(chunk_size, stub.length);

		/* form the dcerpc response packet */
		dcesrv_init_hdr(&pkt,
				lpcfg_rpc_big_endian(call->conn->dce_ctx->lp_ctx));
		pkt.auth_length = 0;
		pkt.call_id = call->pkt.call_id;
		pkt.ptype = DCERPC_PKT_RESPONSE;
		pkt.pfc_flags = 0;
		if (stub.length == total_length) {
			pkt.pfc_flags |= DCERPC_PFC_FLAG_FIRST;
		}
		if (length == stub.length) {
			pkt.pfc_flags |= DCERPC_PFC_FLAG_LAST;
		}
		pkt.u.response.alloc_hint = stub.length;
		pkt.u.response.context_id = call->pkt.u.request.context_id;
		pkt.u.response.cancel_count = 0;
		pkt.u.response._pad.data = call->pkt.u.request._pad.data;
		pkt.u.response._pad.length = call->pkt.u.request._pad.length;
		pkt.u.response.stub_and_verifier.data = stub.data;
		pkt.u.response.stub_and_verifier.length = length;

		if (!dcesrv_auth_response(call, &rep->blob, sig_size, &pkt)) {
			return dcesrv_fault(call, DCERPC_FAULT_OTHER);
		}

		dcerpc_set_frag_length(&rep->blob, rep->blob.length);

		DLIST_ADD_END(call->replies, rep);

		stub.data += length;
		stub.length -= length;
	} while (stub.length != 0);

	/* move the call from the pending to the finished calls list */
	dcesrv_call_set_list(call, DCESRV_LIST_CALL_LIST);

	if (call->conn->call_list && call->conn->call_list->replies) {
		if (call->conn->transport.report_output_data) {
			call->conn->transport.report_output_data(call->conn);
		}
	}

	return NT_STATUS_OK;
}
Example #25
0
/*
  queue a packet for sending
*/
int ctdb_queue_send(struct ctdb_queue *queue, uint8_t *data, uint32_t length)
{
	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(queue, struct ctdb_queue_pkt);
	CTDB_NO_MEMORY(queue->ctdb, pkt);

	pkt->data = talloc_memdup(pkt, data, length2);
	CTDB_NO_MEMORY(queue->ctdb, pkt->data);

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

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

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

	queue->out_queue_length++;

	if (queue->ctdb->tunable.verbose_memory_names != 0) {
		struct ctdb_req_header *hdr = (struct ctdb_req_header *)pkt->data;
		switch (hdr->operation) {
		case CTDB_REQ_CONTROL: {
			struct ctdb_req_control *c = (struct ctdb_req_control *)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 *m = (struct ctdb_req_message *)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;
}
Example #26
0
/*
 * Schedule a new lock child process
 * Set up callback handler and timeout handler
 */
static void ctdb_lock_schedule(struct ctdb_context *ctdb)
{
	struct lock_context *lock_ctx, *next_ctx, *active_ctx;
	int ret;
	TALLOC_CTX *tmp_ctx;
	const char *helper = BINDIR "/ctdb_lock_helper";
	static const char *prog = NULL;
	char **args;

	if (prog == NULL) {
		const char *t;

		t = getenv("CTDB_LOCK_HELPER");
		if (t != NULL) {
			prog = talloc_strdup(ctdb, t);
		} else {
			prog = talloc_strdup(ctdb, helper);
		}
		CTDB_NO_MEMORY_VOID(ctdb, prog);
	}

	if (ctdb->lock_pending == NULL) {
		return;
	}

	/* Find a lock context with requests */
	lock_ctx = ctdb->lock_pending;
	while (lock_ctx != NULL) {
		next_ctx = lock_ctx->next;
		if (! lock_ctx->req_queue) {
			DEBUG(DEBUG_INFO, ("Removing lock context without lock requests\n"));
			DLIST_REMOVE(ctdb->lock_pending, lock_ctx);
			ctdb->lock_num_pending--;
			CTDB_DECREMENT_STAT(ctdb, locks.num_pending);
			if (lock_ctx->ctdb_db) {
				CTDB_DECREMENT_DB_STAT(lock_ctx->ctdb_db, locks.num_pending);
			}
			talloc_free(lock_ctx);
		} else {
			active_ctx = find_lock_context(ctdb->lock_current, lock_ctx->ctdb_db,
						       lock_ctx->key, lock_ctx->priority,
						       lock_ctx->type);
			if (active_ctx == NULL) {
				if (lock_ctx->ctdb_db == NULL ||
				    lock_ctx->ctdb_db->lock_num_current < MAX_LOCK_PROCESSES_PER_DB) {
					/* Found a lock context with lock requests */
					break;
				}
			}

			/* There is already a child waiting for the
			 * same key.  So don't schedule another child
			 * just yet.
			 */
		}
		lock_ctx = next_ctx;
	}

	if (lock_ctx == NULL) {
		return;
	}

	lock_ctx->child = -1;
	ret = pipe(lock_ctx->fd);
	if (ret != 0) {
		DEBUG(DEBUG_ERR, ("Failed to create pipe in ctdb_lock_schedule\n"));
		return;
	}

	set_close_on_exec(lock_ctx->fd[0]);

	/* Create data for child process */
	tmp_ctx = talloc_new(lock_ctx);
	if (tmp_ctx == NULL) {
		DEBUG(DEBUG_ERR, ("Failed to allocate memory for helper args\n"));
		close(lock_ctx->fd[0]);
		close(lock_ctx->fd[1]);
		return;
	}

	/* Create arguments for lock helper */
	args = lock_helper_args(tmp_ctx, lock_ctx, lock_ctx->fd[1]);
	if (args == NULL) {
		DEBUG(DEBUG_ERR, ("Failed to create lock helper args\n"));
		close(lock_ctx->fd[0]);
		close(lock_ctx->fd[1]);
		talloc_free(tmp_ctx);
		return;
	}

	lock_ctx->child = vfork();

	if (lock_ctx->child == (pid_t)-1) {
		DEBUG(DEBUG_ERR, ("Failed to create a child in ctdb_lock_schedule\n"));
		close(lock_ctx->fd[0]);
		close(lock_ctx->fd[1]);
		talloc_free(tmp_ctx);
		return;
	}


	/* Child process */
	if (lock_ctx->child == 0) {
		ret = execv(prog, args);
		if (ret < 0) {
			DEBUG(DEBUG_ERR, ("Failed to execute helper %s (%d, %s)\n",
					  prog, errno, strerror(errno)));
		}
		_exit(1);
	}

	/* Parent process */
	ctdb_track_child(ctdb, lock_ctx->child);
	close(lock_ctx->fd[1]);

	talloc_set_destructor(lock_ctx, ctdb_lock_context_destructor);

	talloc_free(tmp_ctx);

	/* Set up timeout handler */
	lock_ctx->ttimer = tevent_add_timer(ctdb->ev,
					    lock_ctx,
					    timeval_current_ofs(10, 0),
					    ctdb_lock_timeout_handler,
					    (void *)lock_ctx);
	if (lock_ctx->ttimer == NULL) {
		ctdb_kill(ctdb, lock_ctx->child, SIGKILL);
		lock_ctx->child = -1;
		talloc_set_destructor(lock_ctx, NULL);
		close(lock_ctx->fd[0]);
		return;
	}

	/* Set up callback */
	lock_ctx->tfd = tevent_add_fd(ctdb->ev,
				      lock_ctx,
				      lock_ctx->fd[0],
				      EVENT_FD_READ,
				      ctdb_lock_handler,
				      (void *)lock_ctx);
	if (lock_ctx->tfd == NULL) {
		TALLOC_FREE(lock_ctx->ttimer);
		ctdb_kill(ctdb, lock_ctx->child, SIGKILL);
		lock_ctx->child = -1;
		talloc_set_destructor(lock_ctx, NULL);
		close(lock_ctx->fd[0]);
		return;
	}
	tevent_fd_set_auto_close(lock_ctx->tfd);

	/* Move the context from pending to current */
	DLIST_REMOVE(ctdb->lock_pending, lock_ctx);
	ctdb->lock_num_pending--;
	DLIST_ADD_END(ctdb->lock_current, lock_ctx, NULL);
	if (lock_ctx->ctdb_db) {
		lock_ctx->ctdb_db->lock_num_current++;
		CTDB_INCREMENT_STAT(lock_ctx->ctdb, locks.num_current);
		CTDB_INCREMENT_DB_STAT(lock_ctx->ctdb_db, locks.num_current);
	}
}