Пример #1
0
static errno_t
pack_buffer(struct response *r,
            int sysvol_gpt_version,
            int result)
{
    size_t p = 0;

    /* A buffer with the following structure must be created:
     *   uint32_t sysvol_gpt_version (required)
     *   uint32_t status of the request (required)
     */
    r->size = 2 * sizeof(uint32_t);

    r->buf = talloc_array(r, uint8_t, r->size);
    if(r->buf == NULL) {
        return ENOMEM;
    }

    DEBUG(SSSDBG_TRACE_FUNC, "result [%d]\n", result);

    /* sysvol_gpt_version */
    SAFEALIGN_SET_UINT32(&r->buf[p], sysvol_gpt_version, &p);

    /* result */
    SAFEALIGN_SET_UINT32(&r->buf[p], result, &p);

    return EOK;
}
Пример #2
0
static int pack_buffer(struct response *r, int result, krb5_error_code krberr,
                       const char *msg, time_t expire_time)
{
    int len;
    size_t p = 0;

    len = strlen(msg);
    r->size = 2 * sizeof(uint32_t) + sizeof(krb5_error_code) +
              len + sizeof(time_t);

    r->buf = talloc_array(r, uint8_t, r->size);
    if(!r->buf) {
        return ENOMEM;
    }

    /* result */
    SAFEALIGN_SET_UINT32(&r->buf[p], result, &p);

    /* krb5 error code */
    safealign_memcpy(&r->buf[p], &krberr, sizeof(krberr), &p);

    /* message size */
    SAFEALIGN_SET_UINT32(&r->buf[p], len, &p);

    /* message itself */
    safealign_memcpy(&r->buf[p], msg, len, &p);

    /* ticket expiration time */
    safealign_memcpy(&r->buf[p], &expire_time, sizeof(expire_time), &p);

    return EOK;
}
Пример #3
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;
}
Пример #4
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;
}
Пример #5
0
static errno_t create_tgt_req_send_buffer(TALLOC_CTX *mem_ctx,
                                          const char *realm_str,
                                          const char *princ_str,
                                          const char *keytab_name,
                                          int32_t lifetime,
                                          struct io_buffer **io_buf)
{
    struct io_buffer *buf;
    size_t rp;

    buf = talloc(mem_ctx, struct io_buffer);
    if (buf == NULL) {
        DEBUG(1, ("talloc failed.\n"));
        return ENOMEM;
    }

    buf->size = 4 * sizeof(uint32_t);
    if (realm_str) {
        buf->size += strlen(realm_str);
    }
    if (princ_str) {
        buf->size += strlen(princ_str);
    }
    if (keytab_name) {
        buf->size += strlen(keytab_name);
    }

    DEBUG(7, ("buffer size: %d\n", buf->size));

    buf->data = talloc_size(buf, buf->size);
    if (buf->data == NULL) {
        DEBUG(1, ("talloc_size failed.\n"));
        talloc_free(buf);
        return ENOMEM;
    }

    rp = 0;

    /* realm */
    if (realm_str) {
        SAFEALIGN_SET_UINT32(&buf->data[rp], strlen(realm_str), &rp);
        safealign_memcpy(&buf->data[rp], realm_str, strlen(realm_str), &rp);
    } else {
        SAFEALIGN_SET_UINT32(&buf->data[rp], 0, &rp);
    }

    /* principal */
    if (princ_str) {
        SAFEALIGN_SET_UINT32(&buf->data[rp], strlen(princ_str), &rp);
        safealign_memcpy(&buf->data[rp], princ_str, strlen(princ_str), &rp);
    } else {
        SAFEALIGN_SET_UINT32(&buf->data[rp], 0, &rp);
    }

    /* keytab */
    if (keytab_name) {
        SAFEALIGN_SET_UINT32(&buf->data[rp], strlen(keytab_name), &rp);
        safealign_memcpy(&buf->data[rp], keytab_name, strlen(keytab_name), &rp);
    } else {
        SAFEALIGN_SET_UINT32(&buf->data[rp], 0, &rp);
    }

    /* lifetime */
    SAFEALIGN_SET_UINT32(&buf->data[rp], lifetime, &rp);

    *io_buf = buf;
    return EOK;
}
Пример #6
0
errno_t
_sss_getautomntbyname_r(const char *key, char **value, void *context)
{
    int errnop;
    errno_t ret;
    struct automtent *ctx;
    size_t key_len;
    size_t name_len;
    size_t data_len = 0;
    uint8_t *data;
    size_t ctr = 0;
    struct sss_cli_req_data rd;
    uint8_t *repbuf = NULL;
    size_t replen;

    char *buf;
    uint32_t len;
    uint32_t vallen;
    size_t rp;

    sss_nss_lock();

    ctx = (struct automtent *) context;
    if (!ctx || !key) {
        ret = EINVAL;
        goto out;
    }

    /* Be paranoid in case someone tries to smuggle in a huge map name */
    ret = sss_strnlen(ctx->mapname, MAX_AUTOMNTMAPNAME_LEN, &name_len);
    if (ret != 0) {
        ret = EINVAL;
        goto out;
    }

    ret = sss_strnlen(key, MAX_AUTOMNTKEYNAME_LEN, &key_len);
    if (ret != 0) {
        ret = EINVAL;
        goto out;
    }


    data_len = sizeof(uint32_t) +            /* mapname len */
               name_len + 1 +                /* mapname\0   */
               sizeof(uint32_t) +            /* keyname len */
               key_len + 1;                  /* keyname\0   */

    data = malloc(data_len);
    if (!data) {
        ret = ENOMEM;
        goto out;
    }

    SAFEALIGN_SET_UINT32(data, name_len, &ctr);

    safealign_memcpy(data+ctr, ctx->mapname, name_len + 1, &ctr);

    SAFEALIGN_SET_UINT32(data+ctr, key_len, &ctr);

    safealign_memcpy(data+ctr, key, key_len + 1, &ctr);

    rd.data = data;
    rd.len = data_len;

    sss_autofs_make_request(SSS_AUTOFS_GETAUTOMNTBYNAME, &rd,
                            &repbuf, &replen, &errnop);
    free(data);
    if (errnop != 0) {
        ret = errnop;
        goto out;
    }

    /* Got reply, let's parse it */
    rp = 0;
    SAFEALIGN_COPY_UINT32(&len, repbuf+rp, &rp);
    if (len == 0) {
        /* No data */
        *value = NULL;
        ret = ENOENT;
        goto out;
    }

    SAFEALIGN_COPY_UINT32(&vallen, repbuf+rp, &rp);
    if (vallen > len-rp) {
        ret = EIO;
        goto out;
    }

    buf = malloc(vallen);
    if (!buf) {
        ret = ENOMEM;
        goto out;
    }

    safealign_memcpy(buf, repbuf+rp, vallen, &rp);
    *value = buf;

    ret = 0;
out:
    free(repbuf);
    sss_nss_unlock();
    return ret;
}
Пример #7
0
errno_t
_sss_getautomntent_r(char **key, char **value, void *context)
{
    int errnop;
    errno_t ret;
    size_t name_len;
    struct sss_cli_req_data rd;
    uint8_t *repbuf = NULL;
    size_t replen;
    struct automtent *ctx;
    size_t ctr = 0;
    size_t data_len = 0;
    uint8_t *data;

    sss_nss_lock();

    ctx = (struct automtent *) context;
    if (!ctx) {
        ret = EINVAL;
        goto out;
    }

    /* Be paranoid in case someone tries to smuggle in a huge map name */
    ret = sss_strnlen(ctx->mapname, MAX_AUTOMNTMAPNAME_LEN, &name_len);
    if (ret != 0) {
        ret = EINVAL;
        goto out;
    }

    ret = sss_getautomntent_data_return(ctx->mapname, key, value);
    if (ret == EOK) {
        /* The results are available from cache. Just advance the
         * cursor and return. */
        ctx->cursor++;
        ret = 0;
        goto out;
    }
    /* Don't try to handle any error codes, just go to the responder again */

    data_len = sizeof(uint32_t) +            /* mapname len */
               name_len + 1 +                /* mapname\0   */
               sizeof(uint32_t) +            /* index into the map */
               sizeof(uint32_t);             /* num entries to retreive */

    data = malloc(data_len);
    if (!data) {
        ret = ENOMEM;
        goto out;
    }

    SAFEALIGN_SET_UINT32(data, name_len, &ctr);

    safealign_memcpy(data+ctr, ctx->mapname, name_len + 1, &ctr);

    SAFEALIGN_SET_UINT32(data+ctr, ctx->cursor, &ctr);

    SAFEALIGN_SET_UINT32(data+ctr, GETAUTOMNTENT_MAX_ENTRIES, &ctr);

    rd.data = data;
    rd.len = data_len;

    sss_autofs_make_request(SSS_AUTOFS_GETAUTOMNTENT, &rd,
                            &repbuf, &replen, &errnop);
    free(data);
    if (errnop != 0) {
        ret = errnop;
        goto out;
    }

    /* Got reply, let's save it and return from "cache" */
    ret = sss_getautomntent_data_save(ctx->mapname, &repbuf, replen);
    if (ret == ENOENT) {
        /* No results */
        *key = NULL;
        *value = NULL;
        goto out;
    } else if (ret != EOK) {
        /* Unexpected error */
        goto out;
    }

    ret = sss_getautomntent_data_return(ctx->mapname, key, value);
    if (ret != EOK) {
        goto out;
    }

    /* Advance the cursor so that we'll fetch the next map
     * next time getautomntent is called */
    ctx->cursor++;
    ret = 0;
out:
    sss_nss_unlock();
    return ret;
}
Пример #8
0
/* SSH public key request:
 * 
 * header:
 *   0..3: flags (unsigned int, must be combination of SSS_SSH_REQ_* flags)
 *   4..7: name length (unsigned int)
 *   8..X: name (null-terminated UTF-8 string)
 * alias (only included if flags & SSS_SSH_REQ_ALIAS):
 *   0..3: alias length (unsigned int)
 *   4..X: alias (null-terminated UTF-8 string)
 * domain (ony included if flags & SSS_SSH_REQ_DOMAIN):
 *   0..3: domain length (unsigned int, 0 means default domain)
 *   4..X: domain (null-terminated UTF-8 string)
 * 
 * SSH public key reply:
 * 
 * header:
 *   0..3: number of results (unsigned int)
 *   4..7: reserved (unsigned int, must be 0)
 * results (repeated for each result):
 *   0..3:     flags (unsigned int, must be 0)
 *   4..7:     name length (unsigned int)
 *   8..(X-1): name (null-terminated UTF-8 string)
 *   X..(X+3): key length (unsigned int)
 *   (X+4)..Y: key (public key data)
 */
errno_t
sss_ssh_get_ent(TALLOC_CTX *mem_ctx,
                enum sss_cli_command command,
                const char *name,
                const char *domain,
                const char *alias,
                struct sss_ssh_ent **result)
{
    TALLOC_CTX *tmp_ctx;
    struct sss_ssh_ent *res = NULL;
    errno_t ret;
    uint32_t flags;
    uint32_t name_len;
    uint32_t alias_len = 0;
    uint32_t domain_len;
    size_t req_len;
    uint8_t *req = NULL;
    size_t c = 0;
    struct sss_cli_req_data rd;
    int req_ret, req_errno;
    uint8_t *rep = NULL;
    size_t rep_len;
    uint32_t count, reserved, len, i;

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

    /* build request */
    flags = 0;
    name_len = strlen(name)+1;
    req_len = 2*sizeof(uint32_t) + name_len;

    if (alias) {
        flags |= SSS_SSH_REQ_ALIAS;
        alias_len = strlen(alias)+1;
        req_len += sizeof(uint32_t) + alias_len;
    }

    flags |= SSS_SSH_REQ_DOMAIN;
    domain_len = domain ? (strlen(domain)+1) : 0;
    req_len += sizeof(uint32_t) + domain_len;

    req = talloc_array(tmp_ctx, uint8_t, req_len);
    if (!req) {
        ret = ENOMEM;
        goto done;
    }

    SAFEALIGN_SET_UINT32(req+c, flags, &c);
    SAFEALIGN_SET_UINT32(req+c, name_len, &c);
    safealign_memcpy(req+c, name, name_len, &c);
    if (alias) {
        SAFEALIGN_SET_UINT32(req+c, alias_len, &c);
        safealign_memcpy(req+c, alias, alias_len, &c);
    }
    SAFEALIGN_SET_UINT32(req+c, domain_len, &c);
    if (domain_len > 0) {
        safealign_memcpy(req+c, domain, domain_len, &c);
    }

    /* send request */
    rd.data = req;
    rd.len = req_len;

    req_ret = sss_ssh_make_request(command, &rd, &rep, &rep_len, &req_errno);
    if (req_errno != EOK) {
        ret = req_errno;
        goto done;
    }
    if (req_ret != SSS_STATUS_SUCCESS) {
        ret = EFAULT;
        goto done;
    }

    /* parse reply */
    c = 0;
    if (rep_len-c < 2*sizeof(uint32_t)) {
        ret = EINVAL;
        goto done;
    }

    SAFEALIGN_COPY_UINT32(&count, rep+c, &c);

    SAFEALIGN_COPY_UINT32(&reserved, rep+c, &c);
    if (reserved != 0) {
        ret = EINVAL;
        goto done;
    }

    res = talloc_zero(tmp_ctx, struct sss_ssh_ent);
    if (!res) {
        ret = ENOMEM;
        goto done;
    }

    if (count > 0) {
        res->pubkeys = talloc_zero_array(res, struct sss_ssh_pubkey, count);
        if (!res->pubkeys) {
            ret = ENOMEM;
            goto done;
        }

        res->num_pubkeys = count;
    }