コード例 #1
0
ファイル: nsssrv_mmap_cache.c プロジェクト: hujon/sssd
static void sss_mc_invalidate_rec(struct sss_mc_ctx *mcc,
                                  struct sss_mc_rec *rec)
{
    if (rec->b1 == MC_INVALID_VAL) {
        /* record already invalid */
        return;
    }

    /* Remove from hash chains */
    /* hash chain 1 */
    sss_mc_rm_rec_from_chain(mcc, rec, rec->hash1);
    /* hash chain 2 */
    sss_mc_rm_rec_from_chain(mcc, rec, rec->hash2);

    /* Clear from free_table */
    sss_mc_free_slots(mcc, rec);

    /* Invalidate record fields */
    MC_RAISE_INVALID_BARRIER(rec);
    memset(rec->data, MC_INVALID_VAL8, ((MC_SLOT_SIZE * MC_SIZE_TO_SLOTS(rec->len))
                                        - sizeof(struct sss_mc_rec)));
    rec->len = MC_INVALID_VAL32;
    rec->expire = MC_INVALID_VAL64;
    rec->next = MC_INVALID_VAL32;
    rec->hash1 = MC_INVALID_VAL32;
    rec->hash2 = MC_INVALID_VAL32;
    MC_LOWER_BARRIER(rec);
}
コード例 #2
0
ファイル: nsssrv_mmap_cache.c プロジェクト: nguay/SSSD
static struct sss_mc_rec *sss_mc_get_record(struct sss_mc_ctx *mcc,
                                            size_t rec_len,
                                            struct sized_string *key)
{
    struct sss_mc_rec *old_rec = NULL;
    struct sss_mc_rec *rec;
    int old_slots;
    int num_slots;
    uint32_t base_slot;
    int i;

    num_slots = MC_SIZE_TO_SLOTS(rec_len);

    old_rec = sss_mc_find_record(mcc, key);
    if (old_rec) {
        old_slots = MC_SIZE_TO_SLOTS(old_rec->len);

        if (old_slots == num_slots) {
            return old_rec;
        }

        /* slot size changed, invalidate record and fall through to get a
        * fully new record */
        base_slot = MC_PTR_TO_SLOT(mcc->data_table, old_rec);
        sss_mc_invalidate_rec(mcc, old_rec);

        /* and now free slots */
        for (i = 0; i < old_slots; i++) {
            MC_CLEAR_BIT(mcc->free_table, base_slot + i);
        }
    }

    /* we are going to use more space, find enough free slots */
    base_slot = sss_mc_find_free_slots(mcc, num_slots);

    rec = MC_SLOT_TO_PTR(mcc->data_table, base_slot, struct sss_mc_rec);

    /* mark as not valid yet */
    MC_RAISE_INVALID_BARRIER(rec);
    rec->len = rec_len;
    rec->next = MC_INVALID_VAL;
    MC_LOWER_BARRIER(rec);

    /* and now mark slots as used */
    for (i = 0; i < num_slots; i++) {
        MC_SET_BIT(mcc->free_table, base_slot + i);
    }

    return rec;
}
コード例 #3
0
ファイル: nsssrv_mmap_cache.c プロジェクト: nguay/SSSD
static void sss_mc_invalidate_rec(struct sss_mc_ctx *mcc,
                                  struct sss_mc_rec *rec)
{
    if (rec->b1 == MC_INVALID_VAL) {
        /* record already invalid */
        return;
    }

    /* hash chain 1 */
    sss_mc_rm_rec_from_chain(mcc, rec, rec->hash1);
    /* hash chain 2 */
    sss_mc_rm_rec_from_chain(mcc, rec, rec->hash2);

    MC_RAISE_INVALID_BARRIER(rec);
    memset(rec->data, 'X', rec->len - sizeof(struct sss_mc_rec));
    rec->len = MC_INVALID_VAL;
    rec->expire = (uint64_t)-1;
    rec->next = MC_INVALID_VAL;
    rec->hash1 = MC_INVALID_VAL;
    rec->hash2 = MC_INVALID_VAL;
    MC_LOWER_BARRIER(rec);
}
コード例 #4
0
ファイル: nsssrv_mmap_cache.c プロジェクト: nguay/SSSD
static void sss_mc_header_update(struct sss_mc_ctx *mc_ctx, int status)
{
    struct sss_mc_header *h;

    /* update header using barriers */
    h = (struct sss_mc_header *)mc_ctx->mmap_base;
    MC_RAISE_BARRIER(h);
    if (status != SSS_MC_HEADER_RECYCLED) {
        /* no reason to update anything else if the file is recycled */
        h->hash_table = MC_PTR_DIFF(mc_ctx->hash_table, mc_ctx->mmap_base);
        h->free_table = MC_PTR_DIFF(mc_ctx->free_table, mc_ctx->mmap_base);
        h->data_table = MC_PTR_DIFF(mc_ctx->data_table, mc_ctx->mmap_base);
        h->ht_size = mc_ctx->ht_size;
        h->ft_size = mc_ctx->ft_size;
        h->dt_size = mc_ctx->dt_size;
        h->major_vno = SSS_MC_MAJOR_VNO;
        h->minor_vno = SSS_MC_MINOR_VNO;
        h->seed = mc_ctx->seed;
        h->reserved = 0;
    }
    h->status = status;
    MC_LOWER_BARRIER(h);
}
コード例 #5
0
ファイル: nsssrv_mmap_cache.c プロジェクト: nguay/SSSD
int sss_mmap_cache_gr_store(struct sss_mc_ctx *mcc,
                            struct sized_string *name,
                            struct sized_string *pw,
                            gid_t gid, size_t memnum,
                            char *membuf, size_t memsize)
{
    struct sss_mc_rec *rec;
    struct sss_mc_grp_data *data;
    struct sized_string gidkey;
    char gidstr[11];
    size_t data_len;
    size_t rec_len;
    size_t pos;
    int ret;

    ret = snprintf(gidstr, 11, "%ld", (long)gid);
    if (ret > 10) {
        return EINVAL;
    }
    to_sized_string(&gidkey, gidstr);

    data_len = name->len + pw->len + memsize;
    rec_len = sizeof(struct sss_mc_rec) +
              sizeof(struct sss_mc_grp_data) +
              data_len;
    if (rec_len > mcc->dt_size) {
        return ENOMEM;
    }

    rec = sss_mc_get_record(mcc, rec_len, name);

    data = (struct sss_mc_grp_data *)rec->data;
    pos = 0;

    MC_RAISE_BARRIER(rec);

    /* header */
    rec->len = rec_len;
    rec->expire = time(NULL) + mcc->valid_time_slot;
    rec->hash1 = sss_mc_hash(mcc, name->str, name->len);
    rec->hash2 = sss_mc_hash(mcc, gidkey.str, gidkey.len);

    /* group struct */
    data->name = MC_PTR_DIFF(data->strs, data);
    data->gid = gid;
    data->members = memnum;
    data->strs_len = data_len;
    memcpy(&data->strs[pos], name->str, name->len);
    pos += name->len;
    memcpy(&data->strs[pos], pw->str, pw->len);
    pos += pw->len;
    memcpy(&data->strs[pos], membuf, memsize);
    pos += memsize;

    MC_LOWER_BARRIER(rec);

    /* finally chain the rec in the hash table */
    /* name hash first */
    sss_mc_add_rec_to_chain(mcc, rec, rec->hash1);
    /* then gid */
    sss_mc_add_rec_to_chain(mcc, rec, rec->hash2);

    return EOK;
}
コード例 #6
0
ファイル: nsssrv_mmap_cache.c プロジェクト: nguay/SSSD
errno_t sss_mmap_cache_pw_store(struct sss_mc_ctx *mcc,
                                struct sized_string *name,
                                struct sized_string *pw,
                                uid_t uid, gid_t gid,
                                struct sized_string *gecos,
                                struct sized_string *homedir,
                                struct sized_string *shell)
{
    struct sss_mc_rec *rec;
    struct sss_mc_pwd_data *data;
    struct sized_string uidkey;
    char uidstr[11];
    size_t data_len;
    size_t rec_len;
    size_t pos;
    int ret;

    ret = snprintf(uidstr, 11, "%ld", (long)uid);
    if (ret > 10) {
        return EINVAL;
    }
    to_sized_string(&uidkey, uidstr);

    data_len = name->len + pw->len + gecos->len + homedir->len + shell->len;
    rec_len = sizeof(struct sss_mc_rec) +
              sizeof(struct sss_mc_pwd_data) +
              data_len;
    if (rec_len > mcc->dt_size) {
        return ENOMEM;
    }

    rec = sss_mc_get_record(mcc, rec_len, name);

    data = (struct sss_mc_pwd_data *)rec->data;
    pos = 0;

    MC_RAISE_BARRIER(rec);

    /* header */
    rec->len = rec_len;
    rec->expire = time(NULL) + mcc->valid_time_slot;
    rec->hash1 = sss_mc_hash(mcc, name->str, name->len);
    rec->hash2 = sss_mc_hash(mcc, uidkey.str, uidkey.len);

    /* passwd struct */
    data->name = MC_PTR_DIFF(data->strs, data);
    data->uid = uid;
    data->gid = gid;
    data->strs_len = data_len;
    memcpy(&data->strs[pos], name->str, name->len);
    pos += name->len;
    memcpy(&data->strs[pos], pw->str, pw->len);
    pos += pw->len;
    memcpy(&data->strs[pos], gecos->str, gecos->len);
    pos += gecos->len;
    memcpy(&data->strs[pos], homedir->str, homedir->len);
    pos += homedir->len;
    memcpy(&data->strs[pos], shell->str, shell->len);
    pos += shell->len;

    MC_LOWER_BARRIER(rec);

    /* finally chain the rec in the hash table */
    /* name hash first */
    sss_mc_add_rec_to_chain(mcc, rec, rec->hash1);
    /* then uid */
    sss_mc_add_rec_to_chain(mcc, rec, rec->hash2);

    return EOK;
}