Beispiel #1
0
void test_sss_idmap_error_string(void **state)
{
    size_t c;

    for (c = IDMAP_SUCCESS; c < IDMAP_ERR_LAST; c++) {
        assert_string_not_equal(idmap_error_string(c),
                                idmap_error_string(IDMAP_ERR_LAST));
    }
}
Beispiel #2
0
int cifs_idmap_init_plugin(void **handle, const char **errmsg)
{
    struct sssd_ctx *ctx;
    enum idmap_error_code err;

    if (handle == NULL || errmsg == NULL)
        return EINVAL;

    ctx = malloc(sizeof *ctx);
    if (!ctx) {
        *errmsg = "Failed to allocate context";
        return -1;
    }
    ctx->errmsg = errmsg;
    ctx_set_error(ctx, NULL);

    err = sss_idmap_init(NULL, NULL, NULL, &ctx->idmap);
    if (err != IDMAP_SUCCESS) {
        ctx_set_error(ctx, idmap_error_string(err));
        free(ctx);
        return -1;
    }

    *handle = ctx;
    return 0;
}
Beispiel #3
0
/* Test with `getcifsacl file` on client. */
int cifs_idmap_sid_to_str(void *handle, const struct cifs_sid *csid,
                          char **name)
{
    struct sssd_ctx *ctx = handle;
    enum idmap_error_code iderr;
    char *sid;
    enum sss_id_type id_type;
    int err;

    iderr = sss_idmap_bin_sid_to_sid(ctx->idmap, (const uint8_t *) csid,
                                     sizeof(*csid), &sid);
    if (iderr != IDMAP_SUCCESS) {
        ctx_set_error(ctx, idmap_error_string(iderr));
        *name = NULL;
        return -1;
    }

    debug("sid: %s", sid);

    err = sss_nss_getnamebysid(sid, name, &id_type);
    if (err != 0)  {
        ctx_set_error(ctx, strerror(err));
        *name = NULL;
        return -err;
    }

    /* FIXME: Map Samba Unix SIDs? (sid->id and use getpwuid)? */

    debug("name: %s", *name);

    return 0;
}
Beispiel #4
0
errno_t ipa_idmap_init(TALLOC_CTX *mem_ctx,
                       struct sdap_id_ctx *id_ctx,
                       struct sdap_idmap_ctx **_idmap_ctx)
{
    errno_t ret;
    TALLOC_CTX *tmp_ctx;
    enum idmap_error_code err;
    struct sdap_idmap_ctx *idmap_ctx = NULL;

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

    idmap_ctx = talloc_zero(tmp_ctx, struct sdap_idmap_ctx);
    if (!idmap_ctx) {
        ret = ENOMEM;
        goto done;
    }
    idmap_ctx->id_ctx = id_ctx;
    idmap_ctx->find_new_domain = ipa_idmap_find_new_domain;

    /* Initialize the map */
    err = sss_idmap_init(sss_idmap_talloc, idmap_ctx,
                         sss_idmap_talloc_free,
                         &idmap_ctx->map);
    if (err != IDMAP_SUCCESS) {
        DEBUG(SSSDBG_CRIT_FAILURE,
              "Could not initialize the ID map: [%s]\n",
               idmap_error_string(err));
        if (err == IDMAP_OUT_OF_MEMORY) {
            ret = ENOMEM;
        } else {
            ret = EINVAL;
        }
        goto done;
    }

    ret = ipa_idmap_get_ranges_from_sysdb(idmap_ctx, NULL, NULL, false);
    if (ret != EOK) {
        DEBUG(SSSDBG_OP_FAILURE, "ipa_idmap_get_ranges_from_sysdb failed.\n");
        goto done;
    }

    *_idmap_ctx = talloc_steal(mem_ctx, idmap_ctx);
    ret = EOK;

done:
    talloc_free(tmp_ctx);
    return ret;
}
Beispiel #5
0
/**
 * cifs_idmap_sids_to_ids - convert struct cifs_sids to struct cifs_uxids
 * usecase: mount.cifs -o sec=krb5,multiuser,cifsacl,nounix
 * test: ls -n on mounted share
 */
int cifs_idmap_sids_to_ids(void *handle, const struct cifs_sid *csid,
                           const size_t num, struct cifs_uxid *cuxid)
{
    struct sssd_ctx *ctx = handle;
    enum idmap_error_code err;
    int success = -1;
    size_t i;
    char *sid;

    debug("num: %zd", num);

    if (num > UINT_MAX) {
        ctx_set_error(ctx, "num is too large.");
        return EINVAL;
    }

    for (i = 0; i < num; ++i) {
        err = sss_idmap_bin_sid_to_sid(ctx->idmap, (const uint8_t *) &csid[i],
                                       sizeof(csid[i]), &sid);
        if (err != IDMAP_SUCCESS) {
            ctx_set_error(ctx, idmap_error_string(err));
            continue;
        }

        cuxid[i].type = CIFS_UXID_TYPE_UNKNOWN;

        if (sss_sid_to_id(ctx, sid, &cuxid[i]) == 0 ||
            samba_unix_sid_to_id(sid, &cuxid[i]) == 0) {

            debug("setting uid of %s to %d", sid, cuxid[i].id.uid);
            success = 0;
        }

        free(sid);
    }

    return success;
}
Beispiel #6
0
static int sid_to_cifs_sid(struct sssd_ctx *ctx, const char *sid,
                           struct cifs_sid *csid)
{
    uint8_t *bsid = NULL;
    enum idmap_error_code err;
    size_t length;

    err = sss_idmap_sid_to_bin_sid(ctx->idmap,
                                   sid, &bsid, &length);
    if (err != IDMAP_SUCCESS) {
        ctx_set_error(ctx, idmap_error_string(err));
        return -1;
    }
    if (length > sizeof(struct cifs_sid)) {
        ctx_set_error(ctx, "too large sid length");
        free(bsid);
        return -1;
    }

    memcpy(csid, bsid, length);
    sss_idmap_free_bin_sid(ctx->idmap, bsid);

    return 0;
}
Beispiel #7
0
errno_t
sdap_idmap_init(TALLOC_CTX *mem_ctx,
                struct sdap_id_ctx *id_ctx,
                struct sdap_idmap_ctx **_idmap_ctx)
{
    errno_t ret;
    TALLOC_CTX *tmp_ctx;
    enum idmap_error_code err;
    size_t i;
    struct ldb_result *res;
    const char *dom_name;
    const char *sid_str;
    id_t slice_num;
    id_t idmap_lower;
    id_t idmap_upper;
    id_t rangesize;
    bool autorid_mode;
    struct sdap_idmap_ctx *idmap_ctx = NULL;

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

    idmap_ctx = talloc_zero(tmp_ctx, struct sdap_idmap_ctx);
    if (!idmap_ctx) {
        ret = ENOMEM;
        goto done;
    }
    idmap_ctx->id_ctx = id_ctx;
    idmap_ctx->find_new_domain = sdap_idmap_find_new_domain;

    idmap_lower = dp_opt_get_int(idmap_ctx->id_ctx->opts->basic,
                                 SDAP_IDMAP_LOWER);
    idmap_upper = dp_opt_get_int(idmap_ctx->id_ctx->opts->basic,
                                 SDAP_IDMAP_UPPER);
    rangesize = dp_opt_get_int(idmap_ctx->id_ctx->opts->basic,
                               SDAP_IDMAP_RANGESIZE);
    autorid_mode = dp_opt_get_bool(idmap_ctx->id_ctx->opts->basic,
                                   SDAP_IDMAP_AUTORID_COMPAT);

    /* Validate that the values make sense */
    if (rangesize <= 0
            || idmap_upper <= idmap_lower
            || (idmap_upper-idmap_lower) < rangesize)
    {
        DEBUG(SSSDBG_FATAL_FAILURE,
              "Invalid settings for range selection: "
               "[%"SPRIid"][%"SPRIid"][%"SPRIid"]\n",
               idmap_lower, idmap_upper, rangesize);
        ret = EINVAL;
        goto done;
    }

    if (((idmap_upper - idmap_lower) % rangesize) != 0) {
        DEBUG(SSSDBG_CONF_SETTINGS,
              "Range size does not divide evenly. Uppermost range will "
               "not be used\n");
    }

    /* Initialize the map */
    err = sss_idmap_init(sss_idmap_talloc, idmap_ctx,
                         sss_idmap_talloc_free,
                         &idmap_ctx->map);
    if (err != IDMAP_SUCCESS) {
        DEBUG(SSSDBG_CRIT_FAILURE,
              "Could not initialize the ID map: [%s]\n",
               idmap_error_string(err));
        if (err == IDMAP_OUT_OF_MEMORY) {
            ret = ENOMEM;
        } else {
            ret = EINVAL;
        }
        goto done;
    }

    err = sss_idmap_ctx_set_autorid(idmap_ctx->map, autorid_mode);
    err |= sss_idmap_ctx_set_lower(idmap_ctx->map, idmap_lower);
    err |= sss_idmap_ctx_set_upper(idmap_ctx->map, idmap_upper);
    err |= sss_idmap_ctx_set_rangesize(idmap_ctx->map, rangesize);
    if (err != IDMAP_SUCCESS) {
        /* This should never happen */
        DEBUG(SSSDBG_CRIT_FAILURE, "sss_idmap_ctx corrupted\n");
        return EIO;
    }


    /* Setup range for externally managed IDs, i.e. IDs are read from the
     * ldap_user_uid_number and ldap_group_gid_number attributes. */
    if (!dp_opt_get_bool(idmap_ctx->id_ctx->opts->basic, SDAP_ID_MAPPING)) {
        ret = sdap_idmap_add_configured_external_range(idmap_ctx);
        if (ret != EOK) {
            DEBUG(SSSDBG_OP_FAILURE,
                  "sdap_idmap_add_configured_external_range failed.\n");
            goto done;
        }
    }

    /* Read in any existing mappings from the cache */
    ret = sysdb_idmap_get_mappings(tmp_ctx, id_ctx->be->domain, &res);
    if (ret != EOK && ret != ENOENT) {
        DEBUG(SSSDBG_FATAL_FAILURE,
              "Could not read ID mappings from the cache: [%s]\n",
               strerror(ret));
        goto done;
    }

    if (ret == EOK && res->count > 0) {
        DEBUG(SSSDBG_CONF_SETTINGS,
              "Initializing [%d] domains for ID-mapping\n", res->count);

        for (i = 0; i < res->count; i++) {
            dom_name = ldb_msg_find_attr_as_string(res->msgs[i],
                                                   SYSDB_NAME,
                                                   NULL);
            if (!dom_name) {
                /* This should never happen */
                ret = EINVAL;
                goto done;
            }

            sid_str = ldb_msg_find_attr_as_string(res->msgs[i],
                                                  SYSDB_IDMAP_SID_ATTR,
                                                  NULL);
            if (!sid_str) {
                /* This should never happen */
                ret = EINVAL;
                goto done;
            }

            slice_num = ldb_msg_find_attr_as_int(res->msgs[i],
                                                 SYSDB_IDMAP_SLICE_ATTR,
                                                 -1);
            if (slice_num == -1) {
                /* This should never happen */
                ret = EINVAL;
                goto done;
            }

            ret = sdap_idmap_add_domain(idmap_ctx, dom_name,
                                        sid_str, slice_num);
            if (ret != EOK) {
                DEBUG(SSSDBG_CRIT_FAILURE,
                      "Could not add domain [%s][%s][%"SPRIid"] "
                       "to ID map: [%s]\n",
                       dom_name, sid_str, slice_num, strerror(ret));
                goto done;
            }
        }
    } else {
        /* This is the first time we're setting up id-mapping
         * Store the default domain as slice 0
         */
        dom_name = dp_opt_get_string(idmap_ctx->id_ctx->opts->basic, SDAP_IDMAP_DEFAULT_DOMAIN);
        if (!dom_name) {
            /* If it's not explicitly specified, use the SSSD domain name */
            dom_name = idmap_ctx->id_ctx->be->domain->name;
            ret = dp_opt_set_string(idmap_ctx->id_ctx->opts->basic,
                                    SDAP_IDMAP_DEFAULT_DOMAIN,
                                    dom_name);
            if (ret != EOK) goto done;
        }

        sid_str = dp_opt_get_string(idmap_ctx->id_ctx->opts->basic, SDAP_IDMAP_DEFAULT_DOMAIN_SID);
        if (sid_str) {
            /* Set the default domain as slice 0 */
            ret = sdap_idmap_add_domain(idmap_ctx, dom_name,
                                        sid_str, 0);
            if (ret != EOK) {
                DEBUG(SSSDBG_CRIT_FAILURE,
                      "Could not add domain [%s][%s][%u] to ID map: [%s]\n",
                       dom_name, sid_str, 0, strerror(ret));
                goto done;
            }
        } else {
            if (dp_opt_get_bool(idmap_ctx->id_ctx->opts->basic, SDAP_IDMAP_AUTORID_COMPAT)) {
                /* In autorid compatibility mode, we MUST have a slice 0 */
                DEBUG(SSSDBG_CRIT_FAILURE,
                      "WARNING: Autorid compatibility mode selected, "
                       "but %s is not set. UID/GID values may differ "
                       "between clients.\n",
                       idmap_ctx->id_ctx->opts->basic[SDAP_IDMAP_DEFAULT_DOMAIN_SID].opt_name);
            }
            /* Otherwise, we'll just fall back to hash values as they are seen */
        }
    }

    *_idmap_ctx = talloc_steal(mem_ctx, idmap_ctx);
    ret = EOK;

done:
    talloc_free(tmp_ctx);
    return ret;
}