static NTSTATUS ldif_realloc_maps(TALLOC_CTX *mem_ctx,
				  struct samsync_ldif_context *l,
				  uint32_t num_entries)
{
	/* Re-allocate memory for groupmap and accountmap arrays */
	l->groupmap = TALLOC_REALLOC_ARRAY(mem_ctx,
					   l->groupmap,
					   GROUPMAP,
					   num_entries + l->num_alloced);

	l->accountmap = TALLOC_REALLOC_ARRAY(mem_ctx,
					     l->accountmap,
					     ACCOUNTMAP,
					     num_entries + l->num_alloced);

	if (l->groupmap == NULL || l->accountmap == NULL) {
		DEBUG(1,("GROUPMAP talloc failed\n"));
		return NT_STATUS_NO_MEMORY;
	}

	/* Initialize the new records */
	memset(&(l->groupmap[l->num_alloced]), 0,
	       sizeof(GROUPMAP) * num_entries);
	memset(&(l->accountmap[l->num_alloced]), 0,
	       sizeof(ACCOUNTMAP) * num_entries);

	/* Remember how many we alloced this time */
	l->num_alloced += num_entries;

	return NT_STATUS_OK;
}
Exemple #2
0
ssize_t message_push_string(uint8 **outbuf, const char *str, int flags)
{
	size_t buf_size = smb_len(*outbuf) + 4;
	size_t grow_size;
	size_t result;
	uint8 *tmp;

	/*
	 * We need to over-allocate, now knowing what srvstr_push will
	 * actually use. This is very generous by incorporating potential
	 * padding, the terminating 0 and at most 4 chars per UTF-16 code
	 * point.
	 */
	grow_size = (strlen(str) + 2) * 4;

	if (!(tmp = TALLOC_REALLOC_ARRAY(NULL, *outbuf, uint8,
					 buf_size + grow_size))) {
		DEBUG(0, ("talloc failed\n"));
		return -1;
	}

	result = srvstr_push((char *)tmp, SVAL(tmp, smb_flg2),
			     tmp + buf_size, str, grow_size, flags);

	if (result == (size_t)-1) {
		DEBUG(0, ("srvstr_push failed\n"));
		return -1;
	}
	set_message_bcc((char *)tmp, smb_buflen(tmp) + result);

	*outbuf = tmp;

	return result;
}
Exemple #3
0
static NTSTATUS get_acl_blob(TALLOC_CTX *ctx,
			vfs_handle_struct *handle,
			files_struct *fsp,
			const char *name,
			DATA_BLOB *pblob)
{
	size_t size = 1024;
	uint8_t *val = NULL;
	uint8_t *tmp;
	ssize_t sizeret;
	int saved_errno = 0;

	ZERO_STRUCTP(pblob);

  again:

	tmp = TALLOC_REALLOC_ARRAY(ctx, val, uint8_t, size);
	if (tmp == NULL) {
		TALLOC_FREE(val);
		return NT_STATUS_NO_MEMORY;
	}
	val = tmp;

	become_root();
	if (fsp && fsp->fh->fd != -1) {
		sizeret = SMB_VFS_FGETXATTR(fsp, XATTR_NTACL_NAME, val, size);
	} else {
		sizeret = SMB_VFS_GETXATTR(handle->conn, name,
					XATTR_NTACL_NAME, val, size);
	}
	if (sizeret == -1) {
		saved_errno = errno;
	}
	unbecome_root();

	/* Max ACL size is 65536 bytes. */
	if (sizeret == -1) {
		errno = saved_errno;
		if ((errno == ERANGE) && (size != 65536)) {
			/* Too small, try again. */
			size = 65536;
			goto again;
		}

		/* Real error - exit here. */
		TALLOC_FREE(val);
		return map_nt_error_from_unix(errno);
	}

	pblob->data = val;
	pblob->length = sizeret;
	return NT_STATUS_OK;
}
static bool smbconf_txt_do_section(const char *section, void *private_data)
{
	WERROR werr;
	uint32_t idx;
	struct txt_private_data *tpd = (struct txt_private_data *)private_data;
	struct txt_cache *cache = tpd->cache;

	if (smbconf_find_in_array(section, cache->share_names,
				  cache->num_shares, &idx))
	{
		cache->current_share = idx;
		return true;
	}

	werr = smbconf_add_string_to_array(cache, &(cache->share_names),
					   cache->num_shares, section);
	if (!W_ERROR_IS_OK(werr)) {
		return false;
	}
	cache->current_share = cache->num_shares;
	cache->num_shares++;

	cache->param_names = TALLOC_REALLOC_ARRAY(cache,
						  cache->param_names,
						  char **,
						  cache->num_shares);
	if (cache->param_names == NULL) {
		return false;
	}
	cache->param_names[cache->current_share] = NULL;

	cache->param_values = TALLOC_REALLOC_ARRAY(cache,
						   cache->param_values,
						   char **,
						   cache->num_shares);
	if (cache->param_values == NULL) {
		return false;
	}
	cache->param_values[cache->current_share] = NULL;

	cache->num_params = TALLOC_REALLOC_ARRAY(cache,
						 cache->num_params,
						 uint32_t,
						 cache->num_shares);
	if (cache->num_params == NULL) {
		return false;
	}
	cache->num_params[cache->current_share] = 0;

	return true;
}
Exemple #5
0
NTSTATUS add_sid_to_array(TALLOC_CTX *mem_ctx, const DOM_SID *sid,
			  DOM_SID **sids, size_t *num)
{
	*sids = TALLOC_REALLOC_ARRAY(mem_ctx, *sids, DOM_SID,
					     (*num)+1);
	if (*sids == NULL) {
		*num = 0;
		return NT_STATUS_NO_MEMORY;
	}

	sid_copy(&((*sids)[*num]), sid);
	*num += 1;

	return NT_STATUS_OK;
}
Exemple #6
0
BOOL add_sid_to_array(TALLOC_CTX *mem_ctx, const DOM_SID *sid, 
		      DOM_SID **sids, size_t *num)
{
	*sids = TALLOC_REALLOC_ARRAY(mem_ctx, *sids, DOM_SID,
					     (*num)+1);
	if (*sids == NULL) {
		*num = 0;
		return False;
	}

	sid_copy(&((*sids)[*num]), sid);
	*num += 1;

	return True;
}
Exemple #7
0
bool add_rid_to_array_unique(TALLOC_CTX *mem_ctx,
				    uint32 rid, uint32 **pp_rids, size_t *p_num)
{
	size_t i;

	for (i=0; i<*p_num; i++) {
		if ((*pp_rids)[i] == rid)
			return True;
	}
	
	*pp_rids = TALLOC_REALLOC_ARRAY(mem_ctx, *pp_rids, uint32, *p_num+1);

	if (*pp_rids == NULL) {
		*p_num = 0;
		return False;
	}

	(*pp_rids)[*p_num] = rid;
	*p_num += 1;
	return True;
}
Exemple #8
0
static bool privilege_set_add(PRIVILEGE_SET *priv_set, LUID_ATTR set)
{
	LUID_ATTR *new_set;

	/* we can allocate memory to add the new privilege */

	new_set = TALLOC_REALLOC_ARRAY(priv_set->mem_ctx, priv_set->set, LUID_ATTR, priv_set->count + 1);
	if ( !new_set ) {
		DEBUG(0,("privilege_set_add: failed to allocate memory!\n"));
		return False;
	}	

	new_set[priv_set->count].luid.high = set.luid.high;
	new_set[priv_set->count].luid.low = set.luid.low;
	new_set[priv_set->count].attr = set.attr;

	priv_set->count++;
	priv_set->set = new_set;

	return True;
}
Exemple #9
0
/* 
   Initialise DMAPI session. The session is persistant kernel state, 
   so it might already exist, in which case we merely want to 
   reconnect to it. This function should be called as root.
*/
static int dmapi_init_session(struct smbd_dmapi_context *ctx)
{
	char	buf[DM_SESSION_INFO_LEN];
	size_t	buflen;
	uint	    nsessions = 5;
	dm_sessid_t *sessions = NULL;
	char    *version;
	char    *session_name;
	TALLOC_CTX *tmp_ctx = talloc_new(NULL);

	int i, err;

	if (ctx->session_num == 0) {
		session_name = talloc_strdup(tmp_ctx, DMAPI_SESSION_NAME);
	} else {
		session_name = talloc_asprintf(tmp_ctx, "%s%u", DMAPI_SESSION_NAME,
					       ctx->session_num);
	}

	if (session_name == NULL) {
		DEBUG(0,("Out of memory in dmapi_init_session\n"));
		talloc_free(tmp_ctx);
		return -1;
	}
 

	if (dm_init_service(&version) < 0) {
		DEBUG(0, ("dm_init_service failed - disabling DMAPI\n"));
		talloc_free(tmp_ctx);
		return -1;
	}

	ZERO_STRUCT(buf);

	/* Fetch kernel DMAPI sessions until we get any of them */
	do {
		dm_sessid_t *new_sessions;
		nsessions *= 2;
		new_sessions = TALLOC_REALLOC_ARRAY(tmp_ctx, sessions, 
						    dm_sessid_t, nsessions);
		if (new_sessions == NULL) {
			talloc_free(tmp_ctx);
			return -1;
		}

		sessions = new_sessions;
		err = dm_getall_sessions(nsessions, sessions, &nsessions);
	} while (err == -1 && errno == E2BIG);

	if (err == -1) {
		DEBUGADD(DMAPI_TRACE,
			("failed to retrieve DMAPI sessions: %s\n",
			strerror(errno)));
		talloc_free(tmp_ctx);
		return -1;
	}

	/* Look through existing kernel DMAPI sessions to find out ours */
	for (i = 0; i < nsessions; ++i) {
		err = dm_query_session(sessions[i], sizeof(buf), buf, &buflen);
		buf[sizeof(buf) - 1] = '\0';
		if (err == 0 && strcmp(session_name, buf) == 0) {
			ctx->session = sessions[i];
			DEBUGADD(DMAPI_TRACE,
				("attached to existing DMAPI session "
				 "named '%s'\n", buf));
			break;
		}
	}

	/* No session already defined. */
	if (ctx->session == DM_NO_SESSION) {
		err = dm_create_session(DM_NO_SESSION, 
					session_name,
					&ctx->session);
		if (err < 0) {
			DEBUGADD(DMAPI_TRACE,
				("failed to create new DMAPI session: %s\n",
				strerror(errno)));
			ctx->session = DM_NO_SESSION;
			talloc_free(tmp_ctx);
			return -1;
		}

		DEBUG(0, ("created new DMAPI session named '%s' for %s\n",
			  session_name, version));
	}

	if (ctx->session != DM_NO_SESSION) {
		set_effective_capability(DMAPI_ACCESS_CAPABILITY);
	}

	/* 
	   Note that we never end the DMAPI session. It gets re-used if possiblie. 
	   DMAPI session is a kernel resource that is usually lives until server reboot
	   and doesn't get destroed when an application finishes.

	   However, we free list of references to DMAPI sessions we've got from the kernel
	   as it is not needed anymore once we have found (or created) our session.
	 */

	talloc_free(tmp_ctx);
	return 0;
}
Exemple #10
0
static ssize_t unmarshall_rpc_header(pipes_struct *p)
{
    /*
     * Unmarshall the header to determine the needed length.
     */

    prs_struct rpc_in;

    if(p->in_data.pdu_received_len != RPC_HEADER_LEN) {
        DEBUG(0,("unmarshall_rpc_header: assert on rpc header length failed.\n"));
        set_incoming_fault(p);
        return -1;
    }

    prs_init_empty( &rpc_in, p->mem_ctx, UNMARSHALL);
    prs_set_endian_data( &rpc_in, p->endian);

    prs_give_memory( &rpc_in, (char *)&p->in_data.current_in_pdu[0],
                     p->in_data.pdu_received_len, False);

    /*
     * Unmarshall the header as this will tell us how much
     * data we need to read to get the complete pdu.
     * This also sets the endian flag in rpc_in.
     */

    if(!smb_io_rpc_hdr("", &p->hdr, &rpc_in, 0)) {
        DEBUG(0,("unmarshall_rpc_header: failed to unmarshall RPC_HDR.\n"));
        set_incoming_fault(p);
        prs_mem_free(&rpc_in);
        return -1;
    }

    /*
     * Validate the RPC header.
     */

    if(p->hdr.major != 5 && p->hdr.minor != 0) {
        DEBUG(0,("unmarshall_rpc_header: invalid major/minor numbers in RPC_HDR.\n"));
        set_incoming_fault(p);
        prs_mem_free(&rpc_in);
        return -1;
    }

    /*
     * If there's not data in the incoming buffer this should be the start of a new RPC.
     */

    if(prs_offset(&p->in_data.data) == 0) {

        /*
         * AS/U doesn't set FIRST flag in a BIND packet it seems.
         */

        if ((p->hdr.pkt_type == RPC_REQUEST) && !(p->hdr.flags & RPC_FLG_FIRST)) {
            /*
             * Ensure that the FIRST flag is set. If not then we have
             * a stream missmatch.
             */

            DEBUG(0,("unmarshall_rpc_header: FIRST flag not set in first PDU !\n"));
            set_incoming_fault(p);
            prs_mem_free(&rpc_in);
            return -1;
        }

        /*
         * If this is the first PDU then set the endianness
         * flag in the pipe. We will need this when parsing all
         * data in this RPC.
         */

        p->endian = rpc_in.bigendian_data;

        DEBUG(5,("unmarshall_rpc_header: using %sendian RPC\n",
                 p->endian == RPC_LITTLE_ENDIAN ? "little-" : "big-" ));

    } else {

        /*
         * If this is *NOT* the first PDU then check the endianness
         * flag in the pipe is the same as that in the PDU.
         */

        if (p->endian != rpc_in.bigendian_data) {
            DEBUG(0,("unmarshall_rpc_header: FIRST endianness flag (%d) different in next PDU !\n", (int)p->endian));
            set_incoming_fault(p);
            prs_mem_free(&rpc_in);
            return -1;
        }
    }

    /*
     * Ensure that the pdu length is sane.
     */

    if((p->hdr.frag_len < RPC_HEADER_LEN) || (p->hdr.frag_len > RPC_MAX_PDU_FRAG_LEN)) {
        DEBUG(0,("unmarshall_rpc_header: assert on frag length failed.\n"));
        set_incoming_fault(p);
        prs_mem_free(&rpc_in);
        return -1;
    }

    DEBUG(10,("unmarshall_rpc_header: type = %u, flags = %u\n", (unsigned int)p->hdr.pkt_type,
              (unsigned int)p->hdr.flags ));

    p->in_data.pdu_needed_len = (uint32)p->hdr.frag_len - RPC_HEADER_LEN;

    prs_mem_free(&rpc_in);

    p->in_data.current_in_pdu = TALLOC_REALLOC_ARRAY(
                                    p, p->in_data.current_in_pdu, uint8_t, p->hdr.frag_len);
    if (p->in_data.current_in_pdu == NULL) {
        DEBUG(0, ("talloc failed\n"));
        set_incoming_fault(p);
        return -1;
    }

    return 0; /* No extra data processed. */
}
Exemple #11
0
/* Query display info for a domain.  This returns enough information plus a
   bit extra to give an overview of domain users for the User Manager
   application. */
static NTSTATUS query_user_list(struct winbindd_domain *domain,
			       TALLOC_CTX *mem_ctx,
			       uint32 *num_entries, 
			       WINBIND_USERINFO **info)
{
	CLI_POLICY_HND *hnd;
	NTSTATUS result = NT_STATUS_UNSUCCESSFUL;
	POLICY_HND dom_pol;
	BOOL got_dom_pol = False;
	uint32 des_access = SEC_RIGHTS_MAXIMUM_ALLOWED;
	unsigned int i, start_idx, retry;
	uint32 loop_count;

	DEBUG(3,("rpc: query_user_list\n"));

	*num_entries = 0;
	*info = NULL;

	retry = 0;
	do {
		/* Get sam handle */

		if ( !NT_STATUS_IS_OK(result = cm_get_sam_handle(domain, &hnd)) )
			return result;

		/* Get domain handle */

		result = cli_samr_open_domain(hnd->cli, mem_ctx, &hnd->pol,
						des_access, &domain->sid, &dom_pol);

	} while (!NT_STATUS_IS_OK(result) && (retry++ < 1) && hnd && hnd->cli && hnd->cli->fd == -1);

	if (!NT_STATUS_IS_OK(result))
		goto done;

	got_dom_pol = True;

	i = start_idx = 0;
	loop_count = 0;

	do {
		TALLOC_CTX *ctx2;
		uint32 num_dom_users, j;
		uint32 max_entries, max_size;
		SAM_DISPINFO_CTR ctr;
		SAM_DISPINFO_1 info1;

		ZERO_STRUCT( ctr );
		ZERO_STRUCT( info1 );
		ctr.sam.info1 = &info1;
	
		if (!(ctx2 = talloc_init("winbindd enum_users"))) {
			result = NT_STATUS_NO_MEMORY;
			goto done;
		}		

		/* this next bit is copied from net_user_list_internal() */

		get_query_dispinfo_params( loop_count, &max_entries, &max_size );

		result = cli_samr_query_dispinfo(hnd->cli, mem_ctx, &dom_pol,
			&start_idx, 1, &num_dom_users, max_entries, max_size, &ctr);

		loop_count++;

		*num_entries += num_dom_users;

		*info = TALLOC_REALLOC_ARRAY( mem_ctx, *info, WINBIND_USERINFO, *num_entries);

		if (!(*info)) {
			result = NT_STATUS_NO_MEMORY;
			talloc_destroy(ctx2);
			goto done;
		}

		for (j = 0; j < num_dom_users; i++, j++) {
			fstring username, fullname;
			uint32 rid = ctr.sam.info1->sam[j].rid_user;
			
			unistr2_to_ascii( username, &(&ctr.sam.info1->str[j])->uni_acct_name, sizeof(username)-1);
			unistr2_to_ascii( fullname, &(&ctr.sam.info1->str[j])->uni_full_name, sizeof(fullname)-1);
			
			(*info)[i].acct_name = talloc_strdup(mem_ctx, username );
			(*info)[i].full_name = talloc_strdup(mem_ctx, fullname );
			(*info)[i].user_sid = rid_to_talloced_sid(domain, mem_ctx, rid );
			
			/* For the moment we set the primary group for
			   every user to be the Domain Users group.
			   There are serious problems with determining
			   the actual primary group for large domains.
			   This should really be made into a 'winbind
			   force group' smb.conf parameter or
			   something like that. */
			   
			(*info)[i].group_sid = rid_to_talloced_sid(domain, 
				mem_ctx, DOMAIN_GROUP_RID_USERS);
		}

		talloc_destroy(ctx2);

	} while (NT_STATUS_EQUAL(result, STATUS_MORE_ENTRIES));

 done:

	if (got_dom_pol)
		cli_samr_close(hnd->cli, mem_ctx, &dom_pol);

	return result;
}
Exemple #12
0
static bool _reg_perfcount_get_instance_info(struct PERF_INSTANCE_DEFINITION *inst,
					     TALLOC_CTX *mem_ctx,
					     int instId,
					     struct PERF_OBJECT_TYPE *obj,
					     TDB_CONTEXT *names)
{
	TDB_DATA key, data;
	char buf[PERFCOUNT_MAX_LEN], temp[PERFCOUNT_MAX_LEN];
	smb_ucs2_t *name = NULL;
	int pad;

	/* First grab the instance data from the data file */
	memset(temp, 0, PERFCOUNT_MAX_LEN);
	snprintf(temp, PERFCOUNT_MAX_LEN, "i%d", instId);
	_reg_perfcount_make_key(&key, buf, PERFCOUNT_MAX_LEN, obj->ObjectNameTitleIndex, temp);
	if (!_reg_perfcount_get_counter_data(key, &data)) {
		DEBUG(3, ("_reg_perfcount_get_counter_data failed\n"));
		return false;
	}
	if(data.dptr == NULL)
	{
		DEBUG(3, ("_reg_perfcount_get_instance_info: No instance data for instance [%s].\n",
			  buf));
		return False;
	}
	inst->counter_data.ByteLength = data.dsize + sizeof(inst->counter_data.ByteLength);
	inst->counter_data.data = TALLOC_REALLOC_ARRAY(mem_ctx,
						       inst->counter_data.data,
						       uint8,
						       data.dsize);
	if(inst->counter_data.data == NULL)
		return False;
	memset(inst->counter_data.data, 0, data.dsize);
	memcpy(inst->counter_data.data, data.dptr, data.dsize);
	SAFE_FREE(data.dptr);

	/* Fetch instance name */
	memset(temp, 0, PERFCOUNT_MAX_LEN);
	snprintf(temp, PERFCOUNT_MAX_LEN, "i%dname", instId);
	_reg_perfcount_make_key(&key, buf, PERFCOUNT_MAX_LEN, obj->ObjectNameTitleIndex, temp);
	data = tdb_fetch(names, key);
	if(data.dptr == NULL)
	{
		/* Not actually an error, but possibly unintended? -- just logging FYI */
		DEBUG(3, ("_reg_perfcount_get_instance_info: No instance name for instance [%s].\n",
			  buf));
		inst->NameLength = 0;
	}
	else
	{
		memset(buf, 0, PERFCOUNT_MAX_LEN);
		memcpy(buf, data.dptr, MIN(PERFCOUNT_MAX_LEN-1,data.dsize));
		buf[PERFCOUNT_MAX_LEN-1] = '\0';
		inst->NameLength = rpcstr_push_talloc(mem_ctx, &name, buf);
		if (inst->NameLength == (uint32_t)-1 || !name) {
			SAFE_FREE(data.dptr);
			return False;
		}
		inst->data = TALLOC_REALLOC_ARRAY(mem_ctx,
						  inst->data,
						  uint8,
						  inst->NameLength);
		if (inst->data == NULL) {
			SAFE_FREE(data.dptr);
			return False;
		}
		memcpy(inst->data, name, inst->NameLength);
		SAFE_FREE(data.dptr);
	}

	inst->ParentObjectTitleIndex = 0;
	inst->ParentObjectTitlePointer = 0;
	inst->UniqueID = PERF_NO_UNIQUE_ID;
	inst->NameOffset = 6 * sizeof(uint32);

	inst->ByteLength = inst->NameOffset + inst->NameLength;
	/* Need to be aligned on a 64-bit boundary here for counter_data */
	if((pad = (inst->ByteLength % 8)))
	{
		pad = 8 - pad;
		inst->data = TALLOC_REALLOC_ARRAY(mem_ctx,
						  inst->data,
						  uint8,
						  inst->NameLength + pad);
		memset(inst->data + inst->NameLength, 0, pad);
		inst->ByteLength += pad;
	}

	return True;
}
Exemple #13
0
static bool _reg_perfcount_get_counter_info(struct PERF_DATA_BLOCK *block,
					    TALLOC_CTX *mem_ctx,
					    int CounterIndex,
					    struct PERF_OBJECT_TYPE *obj,
					    TDB_CONTEXT *names)
{
	TDB_DATA key, data;
	char buf[PERFCOUNT_MAX_LEN];
	size_t dsize, padding;
	long int data32, dbuf[2];
	int64_t data64;
	uint32 counter_size;

	obj->counters[obj->NumCounters].DefaultScale = 0;
	dbuf[0] = dbuf[1] = 0;
	padding = 0;

	_reg_perfcount_make_key(&key, buf, PERFCOUNT_MAX_LEN, CounterIndex, "type");
	data = tdb_fetch(names, key);
	if(data.dptr == NULL)
	{
		DEBUG(3, ("_reg_perfcount_get_counter_info: No type data for counter [%d].\n", CounterIndex));
		return False;
	}
	memset(buf, 0, PERFCOUNT_MAX_LEN);
	memcpy(buf, data.dptr, data.dsize);
	obj->counters[obj->NumCounters].CounterType = atoi(buf);
	DEBUG(10, ("_reg_perfcount_get_counter_info: Got type [%d] for counter [%d].\n",
		   obj->counters[obj->NumCounters].CounterType, CounterIndex));
	SAFE_FREE(data.dptr);

	/* Fetch the actual data */
	_reg_perfcount_make_key(&key, buf, PERFCOUNT_MAX_LEN, CounterIndex, "");
	_reg_perfcount_get_counter_data(key, &data);
	if(data.dptr == NULL)
	{
		DEBUG(3, ("_reg_perfcount_get_counter_info: No counter data for counter [%d].\n", CounterIndex));
		return False;
	}

	counter_size = _reg_perfcount_get_size_field(obj->counters[obj->NumCounters].CounterType);

	if(counter_size == PERF_SIZE_DWORD)
	{
		dsize = sizeof(data32);
		memset(buf, 0, PERFCOUNT_MAX_LEN);
		memcpy(buf, data.dptr, data.dsize);
		data32 = strtol(buf, NULL, 0);
		if((obj->counters[obj->NumCounters].CounterType & 0x00000F00) == PERF_TYPE_NUMBER)
			obj->counters[obj->NumCounters].DefaultScale = _reg_perfcount_compute_scale((int64_t)data32);
		else
			obj->counters[obj->NumCounters].DefaultScale = 0;
		dbuf[0] = data32;
		padding = (dsize - (obj->counter_data.ByteLength%dsize)) % dsize;
	}
	else if(counter_size == PERF_SIZE_LARGE)
	{
		dsize = sizeof(data64);
		memset(buf, 0, PERFCOUNT_MAX_LEN);
		memcpy(buf, data.dptr, data.dsize);
		data64 = atof(buf);
		if((obj->counters[obj->NumCounters].CounterType & 0x00000F00) == PERF_TYPE_NUMBER)
			obj->counters[obj->NumCounters].DefaultScale = _reg_perfcount_compute_scale(data64);
		else
			obj->counters[obj->NumCounters].DefaultScale = 0;
		memcpy((void *)dbuf, (const void *)&data64, dsize);
		padding = (dsize - (obj->counter_data.ByteLength%dsize)) % dsize;
	}
	else /* PERF_SIZE_VARIABLE_LEN */
	{
		dsize = data.dsize;
		memset(buf, 0, PERFCOUNT_MAX_LEN);
		memcpy(buf, data.dptr, data.dsize);
	}
	SAFE_FREE(data.dptr);

	obj->counter_data.ByteLength += dsize + padding;
	obj->counter_data.data = TALLOC_REALLOC_ARRAY(mem_ctx,
						      obj->counter_data.data,
						      uint8,
						      obj->counter_data.ByteLength - sizeof(uint32));
	if(obj->counter_data.data == NULL)
		return False;
	if(dbuf[0] != 0 || dbuf[1] != 0)
	{
		memcpy((void *)(obj->counter_data.data + 
				(obj->counter_data.ByteLength - (sizeof(uint32) + dsize))), 
		       (const void *)dbuf, dsize);
	}
	else
	{
		/* Handling PERF_SIZE_VARIABLE_LEN */
		memcpy((void *)(obj->counter_data.data +
				(obj->counter_data.ByteLength - (sizeof(uint32) + dsize))),
		       (const void *)buf, dsize);
	}
	obj->counters[obj->NumCounters].CounterOffset = obj->counter_data.ByteLength - dsize;
	if(obj->counters[obj->NumCounters].CounterOffset % dsize != 0)
	{
		DEBUG(3,("Improperly aligned counter [%d]\n", obj->NumCounters));
	}
	obj->counters[obj->NumCounters].CounterSize = dsize;

	return True;
}
Exemple #14
0
/* 
   Initialise DMAPI session. The session is persistant kernel state,
   so it might already exist, in which case we merely want to
   reconnect to it. This function should be called as root.
 */
static int dmapi_init_session(void)
{
	char	buf[DM_SESSION_INFO_LEN];
	size_t	buflen;
	uint	    nsessions = 5;
	dm_sessid_t *sessions = NULL;
	int i, err;
	char *version;

	if (dm_init_service(&version) < 0) {
		DEBUG(0,("dm_init_service failed - disabling DMAPI\n"));
		return -1;
	}

	ZERO_STRUCT(buf);

	do {
		dm_sessid_t *new_sessions;
		nsessions *= 2;
		new_sessions = TALLOC_REALLOC_ARRAY(NULL, sessions, 
						    dm_sessid_t, nsessions);
		if (new_sessions == NULL) {
			talloc_free(sessions);
			return -1;
		}
		sessions = new_sessions;
		err = dm_getall_sessions(nsessions, sessions, &nsessions);
	} while (err == -1 && errno == E2BIG);

	if (err == -1) {
		DEBUGADD(DMAPI_TRACE,
			("failed to retrieve DMAPI sessions: %s\n",
			strerror(errno)));
		talloc_free(sessions);
		return -1;
	}

	for (i = 0; i < nsessions; ++i) {
		err = dm_query_session(sessions[i], sizeof(buf), buf, &buflen);
		buf[sizeof(buf) - 1] = '\0';
		if (err == 0 && strcmp(DMAPI_SESSION_NAME, buf) == 0) {
			samba_dmapi_session = sessions[i];
			DEBUGADD(DMAPI_TRACE,
				("attached to existing DMAPI session "
				 "named '%s'\n", buf));
			break;
		}
	}

	talloc_free(sessions);

	/* No session already defined. */
	if (samba_dmapi_session == DM_NO_SESSION) {
		err = dm_create_session(DM_NO_SESSION, DMAPI_SESSION_NAME,
					&samba_dmapi_session);
		if (err < 0) {
			DEBUGADD(DMAPI_TRACE,
				("failed to create new DMAPI session: %s\n",
				strerror(errno)));
			samba_dmapi_session = DM_NO_SESSION;
			return -1;
		}

		DEBUG(0,("created new DMAPI session named '%s' for %s\n", 
			 DMAPI_SESSION_NAME, version));
	}

	if (samba_dmapi_session != DM_NO_SESSION) {
		set_effective_capability(DMAPI_ACCESS_CAPABILITY);
	}

	/* 
	   Note that we never end the DMAPI session. It gets re-used
	   if possible
	 */

	return 0;
}