Example #1
0
errno_t
nss_protocol_fill_sid(struct nss_ctx *nss_ctx,
                      struct nss_cmd_ctx *cmd_ctx,
                      struct sss_packet *packet,
                      struct cache_req_result *result)
{
    struct ldb_message *msg = result->msgs[0];
    struct sized_string sz_sid;
    enum sss_id_type id_type;
    const char *sid;
    size_t rp = 0;
    size_t body_len;
    uint8_t *body;
    errno_t ret;

    ret = nss_get_id_type(cmd_ctx, result, &id_type);
    if (ret != EOK) {
        return ret;
    }

    sid = ldb_msg_find_attr_as_string(msg, SYSDB_SID_STR, NULL);
    if (sid == NULL) {
        DEBUG(SSSDBG_CRIT_FAILURE, "Missing SID.\n");
        return EINVAL;
    }

    to_sized_string(&sz_sid, sid);

    ret = sss_packet_grow(packet, sz_sid.len + 3 * sizeof(uint32_t));
    if (ret != EOK) {
        DEBUG(SSSDBG_OP_FAILURE, "sss_packet_grow failed.\n");
        return ret;
    }

    sss_packet_get_body(packet, &body, &body_len);

    SAFEALIGN_SET_UINT32(&body[rp], 1, &rp); /* Num results. */
    SAFEALIGN_SET_UINT32(&body[rp], 0, &rp); /* Reserved. */
    SAFEALIGN_SET_UINT32(&body[rp], id_type, &rp);
    SAFEALIGN_SET_STRING(&body[rp], sz_sid.str, sz_sid.len, &rp);

    return EOK;
}
Example #2
0
errno_t
nss_protocol_fill_pwent(struct nss_ctx *nss_ctx,
                        struct nss_cmd_ctx *cmd_ctx,
                        struct sss_packet *packet,
                        struct cache_req_result *result)
{
    TALLOC_CTX *tmp_ctx;
    struct ldb_message *msg;
    struct sized_string pwfield;
    struct sized_string *name;
    struct sized_string gecos;
    struct sized_string homedir;
    struct sized_string shell;
    uint32_t gid;
    uint32_t uid;
    uint32_t num_results;
    size_t rp;
    size_t body_len;
    uint8_t *body;
    int i;
    errno_t ret;

    tmp_ctx = talloc_new(NULL);
    if (tmp_ctx == NULL) {
        return ENOMEM;
    }

    /* First two fields (length and reserved), filled up later. */
    ret = sss_packet_grow(packet, 2 * sizeof(uint32_t));
    if (ret != EOK) {
        return ret;
    }

    rp = 2 * sizeof(uint32_t);

    num_results = 0;
    for (i = 0; i < result->count; i++) {
        talloc_free_children(tmp_ctx);
        msg = result->msgs[i];

        /* Password field content. */
        to_sized_string(&pwfield, nss_get_pwfield(nss_ctx, result->domain));

        ret = nss_get_pwent(tmp_ctx, nss_ctx, result->domain, msg, &uid, &gid,
                            &name, &gecos, &homedir, &shell);
        if (ret != EOK) {
            continue;
        }

        /* Adjust packet size: uid, gid + string fields. */

        ret = sss_packet_grow(packet, 2 * sizeof(uint32_t)
                                          + name->len + gecos.len + homedir.len
                                          + shell.len + pwfield.len);
        if (ret != EOK) {
            goto done;
        }

        sss_packet_get_body(packet, &body, &body_len);

        /* Fill packet. */

        SAFEALIGN_SET_UINT32(&body[rp], uid, &rp);
        SAFEALIGN_SET_UINT32(&body[rp], gid, &rp);
        SAFEALIGN_SET_STRING(&body[rp], name->str, name->len, &rp);
        SAFEALIGN_SET_STRING(&body[rp], pwfield.str, pwfield.len, &rp);
        SAFEALIGN_SET_STRING(&body[rp], gecos.str, gecos.len, &rp);
        SAFEALIGN_SET_STRING(&body[rp], homedir.str, homedir.len, &rp);
        SAFEALIGN_SET_STRING(&body[rp], shell.str, shell.len, &rp);

        num_results++;

        /* Do not store entry in memory cache during enumeration or when
         * requested. */
        if (!cmd_ctx->enumeration
                && (cmd_ctx->flags & SSS_NSS_EX_FLAG_INVALIDATE_CACHE) == 0) {
            ret = sss_mmap_cache_pw_store(&nss_ctx->pwd_mc_ctx, name, &pwfield,
                                          uid, gid, &gecos, &homedir, &shell);
            if (ret != EOK) {
                DEBUG(SSSDBG_MINOR_FAILURE,
                      "Failed to store user %s (%s) in mmap cache [%d]: %s!\n",
                      name->str, result->domain->name, ret, sss_strerror(ret));
            }
        }
    }

    ret = EOK;

done:
    talloc_free(tmp_ctx);

    if (ret != EOK) {
        sss_packet_set_size(packet, 0);
        return ret;
    }

    sss_packet_get_body(packet, &body, &body_len);
    SAFEALIGN_COPY_UINT32(body, &num_results, NULL);
    SAFEALIGN_SETMEM_UINT32(body + sizeof(uint32_t), 0, NULL); /* reserved */

    return EOK;
}