Пример #1
0
static void test_mask(int argc, char *argv[],
					  TALLOC_CTX *mem_ctx,
		      struct smbcli_state *cli)
{
	char *mask, *file;
	int l1, l2, i, l;
	int mc_len = strlen(maskchars);
	int fc_len = strlen(filechars);

	smbcli_mkdir(cli->tree, "\\masktest");

	smbcli_unlink(cli->tree, "\\masktest\\*");

	if (argc >= 2) {
		while (argc >= 2) {
			mask = talloc_strdup(mem_ctx, "\\masktest\\");
			file = talloc_strdup(mem_ctx, "\\masktest\\");
			mask = talloc_strdup_append(mask, argv[0]);
			file = talloc_strdup_append(file, argv[1]);
			testpair(mem_ctx, cli, mask, file);
			argv += 2;
			argc -= 2;
		}
		goto finished;
	}

	while (1) {
		l1 = 1 + random() % max_length;
		l2 = 1 + random() % max_length;
		mask = talloc_strdup(mem_ctx, "\\masktest\\");
		file = talloc_strdup(mem_ctx, "\\masktest\\");
		mask = talloc_realloc_size(mem_ctx, mask, strlen(mask)+l1+1);
		file = talloc_realloc_size(mem_ctx, file, strlen(file)+l2+1);
		l = strlen(mask);
		for (i=0;i<l1;i++) {
			mask[i+l] = maskchars[random() % mc_len];
		}
		mask[l+l1] = 0;

		for (i=0;i<l2;i++) {
			file[i+l] = filechars[random() % fc_len];
		}
		file[l+l2] = 0;

		if (ISDOT(file+l) || ISDOTDOT(file+l) || ISDOTDOT(mask+l)) {
			continue;
		}

		if (strspn(file+l, ".") == strlen(file+l)) continue;

		testpair(mem_ctx, cli, mask, file);
		if (NumLoops && (--NumLoops == 0))
			break;
	}

 finished:
	smbcli_rmdir(cli->tree, "\\masktest");
	talloc_free(mem_ctx);
}
Пример #2
0
static void append_route(struct radius_ctx_st *pctx, const char *route, unsigned len)
{
	unsigned i;
	char *p;

	/* accept route/mask */
	if ((p=strchr(route, '/')) == 0)
		return;

	p = strchr(p, ' ');
	if (p != NULL) {
		len = p - route;
	}

	if (pctx->routes_size == 0) {
		pctx->routes = talloc_size(pctx, sizeof(char*));
	} else {
		pctx->routes = talloc_realloc_size(pctx, pctx->routes,
						   (pctx->routes_size+1)*sizeof(char*));
	}

	if (pctx->routes != NULL) {
		i = pctx->routes_size;
		pctx->routes[i] = talloc_strndup(pctx, route, len);
		if (pctx->routes[i] != NULL)
			pctx->routes_size++;
	}
}
Пример #3
0
static bool check_counters(struct db_context *db, TDB_DATA data)
{
	int i;
	uint32_t *counters, *old_counters;

	counters     = (uint32_t *)data.dptr;
	old_counters = (uint32_t *)old_data.dptr;

	/* check that all the counters are monotonic increasing */
	for (i=0; i < old_data.dsize/sizeof(uint32_t); i++) {
		if (counters[i] < old_counters[i]) {
			printf("[%4u] ERROR: counters has decreased for node %u  From %u to %u\n",
			       (unsigned int)getpid(), i, old_counters[i], counters[i]);
			success = false;
			return false;
		}
	}

	if (old_data.dsize != data.dsize) {
		old_data.dsize = data.dsize;
		old_data.dptr = (unsigned char*)talloc_realloc_size(db, old_data.dptr, old_data.dsize);
	}

	memcpy(old_data.dptr, data.dptr, data.dsize);
	if (verbose) print_counters();

	return true;
}
Пример #4
0
/*
  test realloc
*/
static bool test_realloc(void)
{
	void *root, *p1, *p2;

	printf("test: realloc [\nREALLOC\n]\n");

	root = talloc_new(NULL);

	p1 = talloc_size(root, 10);
	CHECK_SIZE("realloc", p1, 10);

	p1 = talloc_realloc_size(NULL, p1, 20);
	CHECK_SIZE("realloc", p1, 20);

	talloc_new(p1);

	p2 = talloc_realloc_size(p1, NULL, 30);

	talloc_new(p1);

	p2 = talloc_realloc_size(p1, p2, 40);

	CHECK_SIZE("realloc", p2, 40);
	CHECK_SIZE("realloc", root, 60);
	CHECK_BLOCKS("realloc", p1, 4);

	p1 = talloc_realloc_size(NULL, p1, 20);
	CHECK_SIZE("realloc", p1, 60);

	talloc_increase_ref_count(p2);
	torture_assert("realloc", talloc_realloc_size(NULL, p2, 5) == NULL,
		"failed: talloc_realloc() on a referenced pointer should fail\n");
	CHECK_BLOCKS("realloc", p1, 4);

	talloc_realloc_size(NULL, p2, 0);
	talloc_realloc_size(NULL, p2, 0);
	CHECK_BLOCKS("realloc", p1, 3);

	torture_assert("realloc", talloc_realloc_size(NULL, p1, 0x7fffffff) == NULL,
		"failed: oversize talloc should fail\n");

	talloc_realloc_size(NULL, p1, 0);

	CHECK_BLOCKS("realloc", root, 1);
	CHECK_SIZE("realloc", root, 0);

	talloc_free(root);

	printf("success: REALLOC\n");

	return true;
}
Пример #5
0
static struct mp_audio *play(struct af_instance *af, struct mp_audio *data)
{
    struct af_resample *s = af->priv;
    struct mp_audio *in   = data;
    struct mp_audio *out  = af->data;


    int in_size     = data->len;
    int in_samples  = in_size / (data->bps * data->nch);
    int out_samples = avresample_available(s->avrctx) +
        av_rescale_rnd(get_delay(s) + in_samples,
                       s->ctx.out_rate, s->ctx.in_rate, AV_ROUND_UP);
    int out_size    = out->bps * out_samples * out->nch;

    if (talloc_get_size(out->audio) < out_size)
        out->audio = talloc_realloc_size(out, out->audio, out_size);

    af->delay = out->bps * av_rescale_rnd(get_delay(s),
                                          s->ctx.out_rate, s->ctx.in_rate,
                                          AV_ROUND_UP);

#if !USE_SET_CHANNEL_MAPPING
    reorder_channels(data->audio, s->reorder_in, data->bps, data->nch, in_samples);
#endif

    out_samples = avresample_convert(s->avrctx,
            (uint8_t **) &out->audio, out_size, out_samples,
            (uint8_t **) &in->audio,  in_size,  in_samples);

    *data = *out;

#if USE_SET_CHANNEL_MAPPING
    if (needs_reorder(s->reorder_out, out->nch)) {
        if (talloc_get_size(s->reorder_buffer) < out_size)
            s->reorder_buffer = talloc_realloc_size(s, s->reorder_buffer, out_size);
        data->audio = s->reorder_buffer;
        out_samples = avresample_convert(s->avrctx_out,
                (uint8_t **) &data->audio, out_size, out_samples,
                (uint8_t **) &out->audio, out_size, out_samples);
    }
#else
    reorder_channels(data->audio, s->reorder_out, out->bps, out->nch, out_samples);
#endif

    data->len = out->bps * out_samples * out->nch;
    return data;
}
Пример #6
0
static void set_min_out_buffer_size(struct bstr *outbuf, int len)
{
    size_t oldlen = talloc_get_size(outbuf->start);
    if (oldlen < len) {
        assert(outbuf->start);  // talloc context should be already set
	mp_msg(MSGT_DECAUDIO, MSGL_V, "Increasing filtered audio buffer size "
	       "from %zd to %d\n", oldlen, len);
        outbuf->start = talloc_realloc_size(NULL, outbuf->start, len);
    }
}
Пример #7
0
void ip_entries_add(void *pool, const char* ip, unsigned ip_size)
{
	if (ip_entries_size+1 > max_ip_entries_size) {
		max_ip_entries_size += 128;
		ip_entries = talloc_realloc_size(pool, ip_entries, sizeof(ip_entries_st)*max_ip_entries_size);
	}
	
	strlcpy(ip_entries[ip_entries_size].ip, ip, sizeof(ip_entries[ip_entries_size].ip));
	ip_entries[ip_entries_size].ip_size = ip_size;
	ip_entries_size++;
	
	return;
}
Пример #8
0
static struct mp_audio *play(struct af_instance *af, struct mp_audio *data)
{
    struct af_resample *s = af->priv;
    struct mp_audio *in   = data;
    struct mp_audio *out  = af->data;

    out->samples = avresample_available(s->avrctx) +
        av_rescale_rnd(get_delay(s) + in->samples,
                       s->ctx.out_rate, s->ctx.in_rate, AV_ROUND_UP);

    mp_audio_realloc_min(out, out->samples);

    af->delay = get_delay(s) / (double)s->ctx.in_rate;

#if !USE_SET_CHANNEL_MAPPING
    do_reorder(in, s->reorder_in);
#endif

    if (out->samples) {
        out->samples = avresample_convert(s->avrctx,
            (uint8_t **) out->planes, out->samples * out->sstride, out->samples,
            (uint8_t **) in->planes,  in->samples  * in->sstride,  in->samples);
        if (out->samples < 0)
            return NULL; // error
    }

    *data = *out;

#if USE_SET_CHANNEL_MAPPING
    if (needs_reorder(s->reorder_out, out->nch)) {
        if (af_fmt_is_planar(out->format)) {
            reorder_planes(data, s->reorder_out);
        } else {
            int out_size = out->samples * out->sstride;
            if (talloc_get_size(s->reorder_buffer) < out_size)
                s->reorder_buffer = talloc_realloc_size(s, s->reorder_buffer, out_size);
            data->planes[0] = s->reorder_buffer;
            int out_samples = avresample_convert(s->avrctx_out,
                    (uint8_t **) data->planes, out_size, out->samples,
                    (uint8_t **) out->planes, out_size, out->samples);
            assert(out_samples == data->samples);
        }
    }
#else
    do_reorder(data, s->reorder_out);
#endif

    return data;
}
Пример #9
0
static int ibw_append_to_part(struct ibw_conn_priv *pconn,
	struct ibw_part *part, char **pp, uint32_t add_len, int info)
{
	DEBUG(DEBUG_DEBUG, ("ibw_append_to_part: cmid=%p, (bs=%u, len=%u, tr=%u), al=%u, i=%u\n",
		pconn->cm_id, part->bufsize, part->len, part->to_read, add_len, info));

	/* allocate more if necessary - it's an "evergrowing" buffer... */
	if (part->len + add_len > part->bufsize) {
		if (part->buf==NULL) {
			assert(part->len==0);
			part->buf = talloc_size(pconn, add_len);
			if (part->buf==NULL) {
				sprintf(ibw_lasterr, "recv talloc_size error (%u) #%d\n",
					add_len, info);
				return -1;
			}
			part->bufsize = add_len;
		} else {
			part->buf = talloc_realloc_size(pconn,
				part->buf, part->len + add_len);
			if (part->buf==NULL) {
				sprintf(ibw_lasterr, "recv realloc error (%u + %u) #%d\n",
					part->len, add_len, info);
				return -1;
			}
		}
		part->bufsize = part->len + add_len;
	}

	/* consume pp */
	memcpy(part->buf + part->len, *pp, add_len);
	*pp += add_len;
	part->len += add_len;
	part->to_read -= add_len;

	return 0;
}
Пример #10
0
/* =Getgrnam-wrapper======================================================*/
static char *
grow_group_buffer(TALLOC_CTX *mem_ctx,
                  char **buffer, size_t *buflen)
{
    char *newbuf;

    if (*buflen == 0) {
        *buflen = DEFAULT_BUFSIZE;
    }
    if (*buflen < MAX_BUF_SIZE) {
        *buflen *= 2;
    }
    if (*buflen > MAX_BUF_SIZE) {
        *buflen = MAX_BUF_SIZE;
    }

    newbuf = talloc_realloc_size(mem_ctx, *buffer, *buflen);
    if (!newbuf) {
        return NULL;
    }
    *buffer = newbuf;

    return *buffer;
}
Пример #11
0
/*
  grow a SMB2 buffer by the specified amount
*/
static NTSTATUS smb2_grow_buffer(struct smb2_request_buffer *buf, size_t increase)
{
	size_t dynamic_ofs;
	uint8_t *buffer_ptr;
	uint32_t newsize = buf->size + increase;

	/* a packet size should be limited a bit */
	if (newsize >= 0x00FFFFFF) return NT_STATUS_MARSHALL_OVERFLOW;

	if (newsize <= buf->allocated) return NT_STATUS_OK;

	dynamic_ofs = buf->dynamic - buf->buffer;

	buffer_ptr = talloc_realloc_size(buf, buf->buffer, newsize);
	NT_STATUS_HAVE_NO_MEMORY(buffer_ptr);

	buf->buffer	= buffer_ptr;
	buf->hdr	= buf->buffer + NBT_HDR_SIZE;
	buf->body	= buf->hdr    + SMB2_HDR_BODY;
	buf->dynamic	= buf->buffer + dynamic_ofs;
	buf->allocated	= newsize;

	return NT_STATUS_OK;
}
Пример #12
0
		talloc_free(m);
		return NULL;
	}

	if (m == NULL) {
		m = talloc_zero_size(mem_ctx, offsetof(struct ctdb_marshall_buffer, data));
		if (m == NULL) {
			return NULL;
		}
		m->db_id = db_id;
	}

	m_size = talloc_get_size(m);
	r_size = talloc_get_size(r);

	m2 = talloc_realloc_size(mem_ctx, m,  m_size + r_size);
	if (m2 == NULL) {
		talloc_free(m);
		return NULL;
	}

	memcpy(m_size + (uint8_t *)m2, r, r_size);

	talloc_free(r);

	m2->count++;

	return m2;
}

/* we've finished marshalling, return a data blob with the marshalled records */
Пример #13
0
static int enum_users(TALLOC_CTX *mem_ctx,
                      struct proxy_id_ctx *ctx,
                      struct sysdb_ctx *sysdb,
                      struct sss_domain_info *dom)
{
    TALLOC_CTX *tmpctx;
    bool in_transaction = false;
    struct passwd *pwd;
    enum nss_status status;
    size_t buflen;
    char *buffer;
    char *newbuf;
    int ret;
    errno_t sret;
    bool again;
    char *name;

    DEBUG(SSSDBG_TRACE_LIBS, "Enumerating users\n");

    tmpctx = talloc_new(mem_ctx);
    if (!tmpctx) {
        return ENOMEM;
    }

    pwd = talloc_zero(tmpctx, struct passwd);
    if (!pwd) {
        ret = ENOMEM;
        goto done;
    }

    buflen = DEFAULT_BUFSIZE;
    buffer = talloc_size(tmpctx, buflen);
    if (!buffer) {
        ret = ENOMEM;
        goto done;
    }

    ret = sysdb_transaction_start(sysdb);
    if (ret) {
        DEBUG(SSSDBG_CRIT_FAILURE, "Failed to start transaction\n");
        goto done;
    }
    in_transaction = true;

    status = ctx->ops.setpwent();
    if (status != NSS_STATUS_SUCCESS) {
        ret = EIO;
        goto done;
    }

    do {
        again = false;

        /* always zero out the pwd structure */
        memset(pwd, 0, sizeof(struct passwd));

        /* get entry */
        status = ctx->ops.getpwent_r(pwd, buffer, buflen, &ret);

        switch (status) {
            case NSS_STATUS_TRYAGAIN:
                /* buffer too small ? */
                if (buflen < MAX_BUF_SIZE) {
                    buflen *= 2;
                }
                if (buflen > MAX_BUF_SIZE) {
                    buflen = MAX_BUF_SIZE;
                }
                newbuf = talloc_realloc_size(tmpctx, buffer, buflen);
                if (!newbuf) {
                    ret = ENOMEM;
                    goto done;
                }
                buffer = newbuf;
                again = true;
                break;

            case NSS_STATUS_NOTFOUND:

                /* we are done here */
                DEBUG(SSSDBG_TRACE_LIBS, "Enumeration completed.\n");

                ret = sysdb_transaction_commit(sysdb);
                if (ret != EOK) {
                    DEBUG(SSSDBG_CRIT_FAILURE, "Failed to commit transaction\n");
                    goto done;
                }
                in_transaction = false;
                break;

            case NSS_STATUS_SUCCESS:

                DEBUG(SSSDBG_TRACE_LIBS,
                      "User found (%s, %"SPRIuid", %"SPRIgid")\n",
                       pwd->pw_name, pwd->pw_uid, pwd->pw_gid);

                /* uid=0 or gid=0 are invalid values */
                /* also check that the id is in the valid range for this domain
                 */
                if (OUT_OF_ID_RANGE(pwd->pw_uid, dom->id_min, dom->id_max) ||
                    OUT_OF_ID_RANGE(pwd->pw_gid, dom->id_min, dom->id_max)) {

                    DEBUG(SSSDBG_OP_FAILURE, "User [%s] filtered out! (id out"
                        " of range)\n", pwd->pw_name);

                    again = true;
                    break;
                }

                name = sss_create_internal_fqname(tmpctx, pwd->pw_name, dom->name);
                if (name == NULL) {
                    DEBUG(SSSDBG_OP_FAILURE,
                          "failed to create internal name '%s'\n",
                          pwd->pw_name);
                    goto done;
                }
                ret = save_user(dom, pwd, name, NULL);
                if (ret) {
                    /* Do not fail completely on errors.
                     * Just report the failure to save and go on */
                    DEBUG(SSSDBG_OP_FAILURE, "Failed to store user %s."
                                " Ignoring.\n", pwd->pw_name);
                }
                again = true;
                break;

            case NSS_STATUS_UNAVAIL:
                /* "remote" backend unavailable. Enter offline mode */
                ret = ENXIO;
                break;

            default:
                ret = EIO;
                DEBUG(SSSDBG_OP_FAILURE, "proxy -> getpwent_r failed (%d)[%s]"
                            "\n", ret, strerror(ret));
                break;
        }
    } while (again);

done:
    talloc_zfree(tmpctx);
    if (in_transaction) {
        sret = sysdb_transaction_cancel(sysdb);
        if (sret != EOK) {
            DEBUG(SSSDBG_CRIT_FAILURE, "Failed to cancel transaction\n");
        }
    }
    ctx->ops.endpwent();
    return ret;
}
Пример #14
0
void *mprRealloc(void *ptr, uint size)
{
	return talloc_realloc_size(mpr_ctx, ptr, size);
}
Пример #15
0
		return NULL;
	}

	if (m == NULL) {
		m = (struct ctdb_marshall_buffer *)talloc_zero_size(
			mem_ctx, offsetof(struct ctdb_marshall_buffer, data));
		if (m == NULL) {
			goto done;
		}
		m->db_id = db_id;
	}

	m_size = talloc_get_size(m);
	r_size = talloc_get_size(r);

	m2 = (struct ctdb_marshall_buffer *)talloc_realloc_size(
		mem_ctx, m,  m_size + r_size);
	if (m2 == NULL) {
		talloc_free(m);
		goto done;
	}

	memcpy(m_size + (uint8_t *)m2, r, r_size);

	m2->count++;

done:
	talloc_free(r);
	return m2;
}

/* we've finished marshalling, return a data blob with the marshalled records */
Пример #16
0
// Use iconv to convert buf to UTF-8.
// Returns buf.start==NULL on error. Returns buf if cp is NULL, or if there is
// obviously no conversion required (e.g. if cp is "UTF-8").
// Returns a newly allocated buffer if conversion is done and succeeds. The
// buffer will be terminated with 0 for convenience (the terminating 0 is not
// included in the returned length).
// Free the returned buffer with talloc_free().
//  buf: input data
//  cp: iconv codepage (or NULL)
//  flags: combination of MP_ICONV_* flags
//  returns: buf (no conversion), .start==NULL (error), or allocated buffer
bstr mp_iconv_to_utf8(struct mp_log *log, bstr buf, const char *cp, int flags)
{
#if HAVE_ICONV
    if (!cp || !cp[0] || mp_charset_is_utf8(cp))
        return buf;

    if (strcasecmp(cp, "ASCII") == 0)
        return buf;

    if (strcasecmp(cp, "UTF-8-BROKEN") == 0)
        return bstr_sanitize_utf8_latin1(NULL, buf);

    iconv_t icdsc;
    if ((icdsc = iconv_open("UTF-8", cp)) == (iconv_t) (-1)) {
        if (flags & MP_ICONV_VERBOSE)
            mp_err(log, "Error opening iconv with codepage '%s'\n", cp);
        goto failure;
    }

    size_t size = buf.len;
    size_t osize = size;
    size_t ileft = size;
    size_t oleft = size - 1;

    char *outbuf = talloc_size(NULL, osize);
    char *ip = buf.start;
    char *op = outbuf;

    while (1) {
        int clear = 0;
        size_t rc;
        if (ileft)
            rc = iconv(icdsc, &ip, &ileft, &op, &oleft);
        else {
            clear = 1; // clear the conversion state and leave
            rc = iconv(icdsc, NULL, NULL, &op, &oleft);
        }
        if (rc == (size_t) (-1)) {
            if (errno == E2BIG) {
                size_t offset = op - outbuf;
                outbuf = talloc_realloc_size(NULL, outbuf, osize + size);
                op = outbuf + offset;
                osize += size;
                oleft += size;
            } else {
                if (errno == EINVAL && (flags & MP_ICONV_ALLOW_CUTOFF)) {
                    // This is intended for cases where the input buffer is cut
                    // at a random byte position. If this happens in the middle
                    // of the buffer, it should still be an error. We say it's
                    // fine if the error is within 10 bytes of the end.
                    if (ileft <= 10)
                        break;
                }
                if (flags & MP_ICONV_VERBOSE) {
                    mp_err(log, "Error recoding text with codepage '%s'\n", cp);
                }
                talloc_free(outbuf);
                iconv_close(icdsc);
                goto failure;
            }
        } else if (clear)
            break;
    }

    iconv_close(icdsc);

    outbuf[osize - oleft - 1] = 0;
    return (bstr){outbuf, osize - oleft - 1};
#endif

failure:
    return (bstr){0};
}
Пример #17
0
/*
  called when an incoming connection is readable
  This function MUST be safe for reentry via the queue callback!
*/
static void queue_io_read(struct ctdb_queue *queue)
{
	int num_ready = 0;
	ssize_t nread;
	uint8_t *data;
	int navail;

	/* check how much data is available on the socket for immediately
	   guaranteed nonblocking access.
	   as long as we are careful never to try to read more than this
	   we know all reads will be successful and will neither block
	   nor fail with a "data not available right now" error
	*/
	if (ioctl(queue->fd, FIONREAD, &num_ready) != 0) {
		return;
	}
	if (num_ready == 0) {
		/* the descriptor has been closed */
		goto failed;
	}

	if (queue->buffer.data == NULL) {
		/* starting fresh, allocate buf to read data */
		queue->buffer.data = talloc_size(queue, QUEUE_BUFFER_SIZE);
		if (queue->buffer.data == NULL) {
			DEBUG(DEBUG_ERR, ("read error alloc failed for %u\n", num_ready));
			goto failed;
		}
		queue->buffer.size = QUEUE_BUFFER_SIZE;
	} else if (queue->buffer.extend > 0) {
		/* extending buffer */
		data = talloc_realloc_size(queue, queue->buffer.data, queue->buffer.extend);
		if (data == NULL) {
			DEBUG(DEBUG_ERR, ("read error realloc failed for %u\n", queue->buffer.extend));
			goto failed;
		}
		queue->buffer.data = data;
		queue->buffer.size = queue->buffer.extend;
		queue->buffer.extend = 0;
	}

	navail = queue->buffer.size - queue->buffer.length;
	if (num_ready > navail) {
		num_ready = navail;
	}

	if (num_ready > 0) {
		nread = read(queue->fd, queue->buffer.data + queue->buffer.length, num_ready);
		if (nread <= 0) {
			DEBUG(DEBUG_ERR, ("read error nread=%d\n", (int)nread));
			goto failed;
		}
		queue->buffer.length += nread;
	}

	queue_process(queue);
	return;

failed:
	queue->callback(NULL, 0, queue->private_data);
}
Пример #18
0
static bool test_pool_steal(void)
{
	void *root;
	void *pool;
	void *p1, *p2;
	void *p1_2, *p2_2;
	size_t hdr;
	size_t ofs1, ofs2;

	root = talloc_new(NULL);
	pool = talloc_pool(root, 1024);

	p1 = talloc_size(pool, 4 * 16);
	torture_assert("pool allocate 4 * 16", p1 != NULL, "failed ");
	memset(p1, 0x11, talloc_get_size(p1));
	p2 = talloc_size(pool, 4 * 16);
	torture_assert("pool allocate 4 * 16", p2 > p1, "failed: !(p2 > p1) ");
	memset(p2, 0x11, talloc_get_size(p2));

	ofs1 = PTR_DIFF(p2, p1);
	hdr = ofs1 - talloc_get_size(p1);

	talloc_steal(root, p1);
	talloc_steal(root, p2);

	talloc_free(pool);

	p1_2 = p1;

#if 1 /* this relies on ALWAYS_REALLOC == 0 in talloc.c */
	p1_2 = talloc_realloc_size(root, p1, 5 * 16);
	torture_assert("pool realloc 5 * 16", p1_2 > p2, "failed: pointer not changed");
	memset(p1_2, 0x11, talloc_get_size(p1_2));
	ofs1 = PTR_DIFF(p1_2, p2);
	ofs2 = talloc_get_size(p2) + hdr;

	torture_assert("pool realloc ", ofs1 == ofs2, "failed: pointer offset unexpected");

	p2_2 = talloc_realloc_size(root, p2, 3 * 16);
	torture_assert("pool realloc 5 * 16", p2_2 == p2, "failed: pointer changed");
	memset(p2_2, 0x11, talloc_get_size(p2_2));
#endif /* this relies on ALWAYS_REALLOC == 0 in talloc.c */

	talloc_free(p1_2);

	p2_2 = p2;

#if 1 /* this relies on ALWAYS_REALLOC == 0 in talloc.c */
	/* now we should reclaim the full pool */
	p2_2 = talloc_realloc_size(root, p2, 8 * 16);
	torture_assert("pool realloc 8 * 16", p2_2 == p1, "failed: pointer not expected");
	p2 = p2_2;
	memset(p2_2, 0x11, talloc_get_size(p2_2));

	/* now we malloc and free the full pool space */
	p2_2 = talloc_realloc_size(root, p2, 2 * 1024);
	torture_assert("pool realloc 2 * 1024", p2_2 != p1, "failed: pointer not expected");
	memset(p2_2, 0x11, talloc_get_size(p2_2));

#endif /* this relies on ALWAYS_REALLOC == 0 in talloc.c */

	talloc_free(p2_2);

	talloc_free(root);

	return true;
}
Пример #19
0
static bool test_pool(void)
{
	void *pool;
	void *p1, *p2, *p3, *p4;
	void *p2_2;

	pool = talloc_pool(NULL, 1024);

	p1 = talloc_size(pool, 80);
	memset(p1, 0x11, talloc_get_size(p1));
	p2 = talloc_size(pool, 20);
	memset(p2, 0x11, talloc_get_size(p2));
	p3 = talloc_size(p1, 50);
	memset(p3, 0x11, talloc_get_size(p3));
	p4 = talloc_size(p3, 1000);
	memset(p4, 0x11, talloc_get_size(p4));

#if 1 /* this relies on ALWAYS_REALLOC == 0 in talloc.c */
	p2_2 = talloc_realloc_size(pool, p2, 20+1);
	torture_assert("pool realloc 20+1", p2_2 == p2, "failed: pointer changed");
	memset(p2, 0x11, talloc_get_size(p2));
	p2_2 = talloc_realloc_size(pool, p2, 20-1);
	torture_assert("pool realloc 20-1", p2_2 == p2, "failed: pointer changed");
	memset(p2, 0x11, talloc_get_size(p2));
	p2_2 = talloc_realloc_size(pool, p2, 20-1);
	torture_assert("pool realloc 20-1", p2_2 == p2, "failed: pointer changed");
	memset(p2, 0x11, talloc_get_size(p2));

	talloc_free(p3);

	/* this should reclaim the memory of p4 and p3 */
	p2_2 = talloc_realloc_size(pool, p2, 400);
	torture_assert("pool realloc 400", p2_2 == p2, "failed: pointer changed");
	memset(p2, 0x11, talloc_get_size(p2));

	talloc_free(p1);

	/* this should reclaim the memory of p1 */
	p2_2 = talloc_realloc_size(pool, p2, 800);
	torture_assert("pool realloc 800", p2_2 == p1, "failed: pointer not changed");
	p2 = p2_2;
	memset(p2, 0x11, talloc_get_size(p2));

	/* this should do a malloc */
	p2_2 = talloc_realloc_size(pool, p2, 1800);
	torture_assert("pool realloc 1800", p2_2 != p2, "failed: pointer not changed");
	p2 = p2_2;
	memset(p2, 0x11, talloc_get_size(p2));

	/* this should reclaim the memory from the pool */
	p3 = talloc_size(pool, 80);
	torture_assert("pool alloc 80", p3 == p1, "failed: pointer changed");
	memset(p3, 0x11, talloc_get_size(p3));

	talloc_free(p2);
	talloc_free(p3);

	p1 = talloc_size(pool, 80);
	memset(p1, 0x11, talloc_get_size(p1));
	p2 = talloc_size(pool, 20);
	memset(p2, 0x11, talloc_get_size(p2));

	talloc_free(p1);

	p2_2 = talloc_realloc_size(pool, p2, 20-1);
	torture_assert("pool realloc 20-1", p2_2 == p2, "failed: pointer changed");
	memset(p2, 0x11, talloc_get_size(p2));
	p2_2 = talloc_realloc_size(pool, p2, 20-1);
	torture_assert("pool realloc 20-1", p2_2 == p2, "failed: pointer changed");
	memset(p2, 0x11, talloc_get_size(p2));

	/* this should do a malloc */
	p2_2 = talloc_realloc_size(pool, p2, 1800);
	torture_assert("pool realloc 1800", p2_2 != p2, "failed: pointer not changed");
	p2 = p2_2;
	memset(p2, 0x11, talloc_get_size(p2));

	/* this should reclaim the memory from the pool */
	p3 = talloc_size(pool, 800);
	torture_assert("pool alloc 800", p3 == p1, "failed: pointer changed");
	memset(p3, 0x11, talloc_get_size(p3));

#endif /* this relies on ALWAYS_REALLOC == 0 in talloc.c */

	talloc_free(pool);

	return true;
}
Пример #20
0
static int get_initgr_groups_process(TALLOC_CTX *memctx,
                                     struct proxy_id_ctx *ctx,
                                     struct sysdb_ctx *sysdb,
                                     struct sss_domain_info *dom,
                                     struct passwd *pwd)
{
    enum nss_status status;
    long int limit;
    long int size;
    long int num;
    long int num_gids;
    gid_t *gids;
    int ret;
    int i;
    time_t now;

    num_gids = 0;
    limit = 4096;
    num = 4096;
    size = num*sizeof(gid_t);
    gids = talloc_size(memctx, size);
    if (!gids) {
        return ENOMEM;
    }

    /* nss modules may skip the primary group when we pass it in so always add
     * it in advance */
    gids[0] = pwd->pw_gid;
    num_gids++;

    /* FIXME: should we move this call outside the transaction to keep the
     * transaction as short as possible ? */
    do {
        status = ctx->ops.initgroups_dyn(pwd->pw_name, pwd->pw_gid, &num_gids,
                                         &num, &gids, limit, &ret);

        if (status == NSS_STATUS_TRYAGAIN) {
            /* buffer too small ? */
            if (size < MAX_BUF_SIZE) {
                num *= 2;
                size = num*sizeof(gid_t);
            }
            if (size > MAX_BUF_SIZE) {
                size = MAX_BUF_SIZE;
                num = size/sizeof(gid_t);
            }
            limit = num;
            gids = talloc_realloc_size(memctx, gids, size);
            if (!gids) {
                return ENOMEM;
            }
        }
    } while(status == NSS_STATUS_TRYAGAIN);

    switch (status) {
    case NSS_STATUS_NOTFOUND:
        DEBUG(SSSDBG_FUNC_DATA, "The initgroups call returned 'NOTFOUND'. "
              "Assume the user is only member of its "
              "primary group (%"SPRIgid")\n", pwd->pw_gid);
    /* fall through */
    case NSS_STATUS_SUCCESS:
        DEBUG(SSSDBG_CONF_SETTINGS, "User [%s] appears to be member of %lu "
              "groups\n", pwd->pw_name, num_gids);

        now = time(NULL);
        for (i = 0; i < num_gids; i++) {
            ret = get_gr_gid(memctx, ctx, sysdb, dom, gids[i], now);
            if (ret) {
                return ret;
            }
        }
        ret = EOK;

        break;

    default:
        DEBUG(SSSDBG_OP_FAILURE, "proxy -> initgroups_dyn failed (%d)[%s]\n",
              ret, strerror(ret));
        ret = EIO;
        break;
    }

    return ret;
}
Пример #21
0
static int get_initgr_groups_process(TALLOC_CTX *memctx,
                                     struct proxy_id_ctx *ctx,
                                     struct sysdb_ctx *sysdb,
                                     struct sss_domain_info *dom,
                                     struct passwd *pwd)
{
    enum nss_status status;
    long int limit;
    long int size;
    long int num;
    long int num_gids;
    gid_t *gids;
    int ret;
    int i;
    time_t now;

    num_gids = 0;
    limit = 4096;
    num = 4096;
    size = num*sizeof(gid_t);
    gids = talloc_size(memctx, size);
    if (!gids) {
        return ENOMEM;
    }

    /* FIXME: should we move this call outside the transaction to keep the
     * transaction as short as possible ? */
    do {
        status = ctx->ops.initgroups_dyn(pwd->pw_name, pwd->pw_gid, &num_gids,
                &num, &gids, limit, &ret);

        if (status == NSS_STATUS_TRYAGAIN) {
            /* buffer too small ? */
            if (size < MAX_BUF_SIZE) {
                num *= 2;
                size = num*sizeof(gid_t);
            }
            if (size > MAX_BUF_SIZE) {
                size = MAX_BUF_SIZE;
                num = size/sizeof(gid_t);
            }
            limit = num;
            gids = talloc_realloc_size(memctx, gids, size);
            if (!gids) {
                return ENOMEM;
            }
        }
    } while(status == NSS_STATUS_TRYAGAIN);

    switch (status) {
    case NSS_STATUS_SUCCESS:
        DEBUG(SSSDBG_CONF_SETTINGS, ("User [%s] appears to be member of %lu"
                    "groups\n", pwd->pw_name, num_gids));

        now = time(NULL);
        for (i = 0; i < num_gids; i++) {
            ret = get_gr_gid(memctx, ctx, sysdb, dom, gids[i], now);
            if (ret) {
                return ret;
            }
        }
        ret = EOK;

        break;

    default:
        DEBUG(2, ("proxy -> initgroups_dyn failed (%d)[%s]\n",
                  ret, strerror(ret)));
        ret = EIO;
        break;
    }

    return ret;
}
Пример #22
0
errno_t
enum_services(struct proxy_id_ctx *ctx,
              struct sysdb_ctx *sysdb,
              struct sss_domain_info *dom)
{
    TALLOC_CTX *tmpctx;
    bool in_transaction = false;
    struct servent *svc;
    enum nss_status status;
    size_t buflen;
    char *buffer;
    char *newbuf;
    errno_t ret, sret;
    time_t now = time(NULL);
    const char **protocols;
    const char **cased_aliases;
    bool again;

    DEBUG(SSSDBG_TRACE_FUNC, "Enumerating services\n");

    tmpctx = talloc_new(NULL);
    if (!tmpctx) {
        return ENOMEM;
    }

    svc = talloc(tmpctx, struct servent);
    if (!svc) {
        ret = ENOMEM;
        goto done;
    }

    buflen = DEFAULT_BUFSIZE;
    buffer = talloc_size(tmpctx, buflen);
    if (!buffer) {
        ret = ENOMEM;
        goto done;
    }

    protocols = talloc_zero_array(tmpctx, const char *, 2);
    if (protocols == NULL) {
        ret = ENOMEM;
        goto done;
    }

    ret = sysdb_transaction_start(sysdb);
    if (ret) {
        DEBUG(SSSDBG_CRIT_FAILURE, "Failed to start transaction\n");
        goto done;
    }
    in_transaction = true;

    status = ctx->ops.setservent();
    if (status != NSS_STATUS_SUCCESS) {
        ret = EIO;
        goto done;
    }

    do {
        again = false;

        /* always zero out the svc structure */
        memset(svc, 0, sizeof(struct servent));

        /* get entry */
        status = ctx->ops.getservent_r(svc, buffer, buflen, &ret);

        switch (status) {
        case NSS_STATUS_TRYAGAIN:
            /* buffer too small ? */
            if (buflen < MAX_BUF_SIZE) {
                buflen *= 2;
            }
            if (buflen > MAX_BUF_SIZE) {
                buflen = MAX_BUF_SIZE;
            }
            newbuf = talloc_realloc_size(tmpctx, buffer, buflen);
            if (!newbuf) {
                ret = ENOMEM;
                goto done;
            }
            buffer = newbuf;
            again = true;
            break;

        case NSS_STATUS_NOTFOUND:

            /* we are done here */
            DEBUG(SSSDBG_TRACE_FUNC, "Enumeration completed.\n");

            ret = sysdb_transaction_commit(sysdb);
            if (ret != EOK) {
                DEBUG(SSSDBG_CRIT_FAILURE, "Failed to commit transaction\n");
                goto done;
            }

            in_transaction = false;
            break;

        case NSS_STATUS_SUCCESS:

            DEBUG(SSSDBG_TRACE_INTERNAL,
                  "Service found (%s, %d/%s)\n",
                  svc->s_name, svc->s_port, svc->s_proto);

            protocols[0] = sss_get_cased_name(protocols, svc->s_proto,
                                              dom->case_sensitive);
            if (!protocols[0]) {
                ret = ENOMEM;
                goto done;
            }
            protocols[1] = NULL;

            ret = sss_get_cased_name_list(tmpctx,
                                          (const char * const *) svc->s_aliases,
                                          dom->case_sensitive, &cased_aliases);
            if (ret != EOK) {
                /* Do not fail completely on errors.
                 * Just report the failure to save and go on */
                DEBUG(SSSDBG_OP_FAILURE,
                      "Failed to store service [%s]. Ignoring.\n",
                      strerror(ret));
                again = true;
                break;
            }

            ret = sysdb_store_service(dom,
                                      svc->s_name,
                                      svc->s_port,
                                      cased_aliases,
                                      protocols,
                                      NULL, NULL,
                                      dom->service_timeout,
                                      now);
            if (ret) {
                /* Do not fail completely on errors.
                 * Just report the failure to save and go on */
                DEBUG(SSSDBG_OP_FAILURE,
                      "Failed to store service [%s]. Ignoring.\n",
                      strerror(ret));
            }
            again = true;
            break;

        case NSS_STATUS_UNAVAIL:
            /* "remote" backend unavailable. Enter offline mode */
            ret = ENXIO;
            break;

        default:
            ret = EIO;
            DEBUG(SSSDBG_CRIT_FAILURE,
                  "proxy -> getservent_r failed (%d)[%s]\n",
                  ret, strerror(ret));
            break;
        }
    } while (again);

done:
    talloc_zfree(tmpctx);
    if (in_transaction) {
        sret = sysdb_transaction_cancel(sysdb);
        if (sret != EOK) {
            DEBUG(SSSDBG_CRIT_FAILURE,
                  "Could not cancel transaction! [%s]\n",
                  strerror(sret));
        }
    }
    ctx->ops.endservent();
    return ret;
}
Пример #23
0
static int enum_groups(TALLOC_CTX *mem_ctx,
                       struct proxy_id_ctx *ctx,
                       struct sysdb_ctx *sysdb,
                       struct sss_domain_info *dom)
{
    TALLOC_CTX *tmpctx;
    bool in_transaction = false;
    struct group *grp;
    enum nss_status status;
    size_t buflen;
    char *buffer;
    char *newbuf;
    int ret;
    errno_t sret;
    bool again;

    DEBUG(SSSDBG_TRACE_LIBS, "Enumerating groups\n");

    tmpctx = talloc_new(mem_ctx);
    if (!tmpctx) {
        return ENOMEM;
    }

    grp = talloc(tmpctx, struct group);
    if (!grp) {
        ret = ENOMEM;
        goto done;
    }

    buflen = DEFAULT_BUFSIZE;
    buffer = talloc_size(tmpctx, buflen);
    if (!buffer) {
        ret = ENOMEM;
        goto done;
    }

    ret = sysdb_transaction_start(sysdb);
    if (ret) {
        DEBUG(SSSDBG_CRIT_FAILURE, "Failed to start transaction\n");
        goto done;
    }
    in_transaction = true;

    status = ctx->ops.setgrent();
    if (status != NSS_STATUS_SUCCESS) {
        ret = EIO;
        goto done;
    }

    do {
        again = false;

        /* always zero out the grp structure */
        memset(grp, 0, sizeof(struct group));

        /* get entry */
        status = ctx->ops.getgrent_r(grp, buffer, buflen, &ret);

        switch (status) {
        case NSS_STATUS_TRYAGAIN:
            /* buffer too small ? */
            if (buflen < MAX_BUF_SIZE) {
                buflen *= 2;
            }
            if (buflen > MAX_BUF_SIZE) {
                buflen = MAX_BUF_SIZE;
            }
            newbuf = talloc_realloc_size(tmpctx, buffer, buflen);
            if (!newbuf) {
                ret = ENOMEM;
                goto done;
            }
            buffer = newbuf;
            again = true;
            break;

        case NSS_STATUS_NOTFOUND:

            /* we are done here */
            DEBUG(SSSDBG_TRACE_LIBS, "Enumeration completed.\n");

            ret = sysdb_transaction_commit(sysdb);
            if (ret != EOK) {
                DEBUG(SSSDBG_CRIT_FAILURE, "Failed to commit transaction\n");
                goto done;
            }
            in_transaction = false;
            break;

        case NSS_STATUS_SUCCESS:

            DEBUG(SSSDBG_OP_FAILURE, "Group found (%s, %"SPRIgid")\n",
                  grp->gr_name, grp->gr_gid);

            /* gid=0 is an invalid value */
            /* also check that the id is in the valid range for this domain
             */
            if (OUT_OF_ID_RANGE(grp->gr_gid, dom->id_min, dom->id_max)) {

                DEBUG(SSSDBG_OP_FAILURE, "Group [%s] filtered out! (id"
                      "out of range)\n", grp->gr_name);

                again = true;
                break;
            }

            ret = save_group(sysdb, dom, grp, grp->gr_name,
                             NULL, dom->group_timeout);
            if (ret) {
                /* Do not fail completely on errors.
                 * Just report the failure to save and go on */
                DEBUG(SSSDBG_OP_FAILURE, "Failed to store group."
                      "Ignoring\n");
            }
            again = true;
            break;

        case NSS_STATUS_UNAVAIL:
            /* "remote" backend unavailable. Enter offline mode */
            ret = ENXIO;
            break;

        default:
            ret = EIO;
            DEBUG(SSSDBG_OP_FAILURE, "proxy -> getgrent_r failed (%d)[%s]"
                  "\n", ret, strerror(ret));
            break;
        }
    } while (again);

done:
    talloc_zfree(tmpctx);
    if (in_transaction) {
        sret = sysdb_transaction_cancel(sysdb);
        if (sret != EOK) {
            DEBUG(SSSDBG_CRIT_FAILURE, "Failed to cancel transaction\n");
        }
    }
    ctx->ops.endgrent();
    return ret;
}