Exemple #1
0
static int
hybrid_domain_user_to_group(struct cache_req_result *result)
{
    errno_t ret;
    uid_t uid;
    gid_t gid;

    /* There must be exactly one entry.. */
    if (result == NULL || result->count != 1) {
        DEBUG(SSSDBG_CRIT_FAILURE,
              "No result or wrong number of entries, expected 1 entry\n");
        return ENOENT;
    }

    /* ...which has uidNumber equal to gidNumber */
    uid = sss_view_ldb_msg_find_attr_as_uint64(result->domain,
                                               result->msgs[0],
                                               SYSDB_UIDNUM,
                                               0);

    gid = sss_view_ldb_msg_find_attr_as_uint64(result->domain,
                                               result->msgs[0],
                                               SYSDB_GIDNUM,
                                               0);

    if (uid == 0 || uid != gid) {
        DEBUG(SSSDBG_TRACE_INTERNAL, "UID and GID differ\n");
        return ENOENT;
    }

    /* OK, we have a user with uid == gid; let's pretend this is a group */
    ret = ldb_msg_add_string(result->msgs[0],
                             SYSDB_OBJECTCATEGORY,
                             SYSDB_GROUP_CLASS);
    if (ret != EOK) {
        DEBUG(SSSDBG_CRIT_FAILURE, "Cannot add group class\n");
        return ret;
    }

    return EOK;
}
Exemple #2
0
static struct cache_req_data *
hybrid_domain_verify_gid_data(TALLOC_CTX *mem_ctx,
                              struct cache_req_result *user_group)
{
    gid_t gid;

    /* read the GID of this 'group' and use it to construct
     * a cache_req_data struct
     */
    gid = sss_view_ldb_msg_find_attr_as_uint64(user_group->domain,
                                               user_group->msgs[0],
                                               SYSDB_GIDNUM,
                                               0);
    if (gid == 0) {
        DEBUG(SSSDBG_CRIT_FAILURE, "A user with no GID?\n");
        return NULL;
    }

    return cache_req_data_id(mem_ctx,
                             CACHE_REQ_GROUP_BY_ID,
                             gid);
}
Exemple #3
0
static errno_t
nss_get_pwent(TALLOC_CTX *mem_ctx,
              struct nss_ctx *nss_ctx,
              struct sss_domain_info *domain,
              struct ldb_message *msg,
              uint32_t *_uid,
              uint32_t *_gid,
              struct sized_string **_name,
              struct sized_string *_gecos,
              struct sized_string *_homedir,
              struct sized_string *_shell)
{
    const char *upn;
    const char *name;
    const char *gecos;
    const char *homedir;
    const char *shell;
    uint32_t gid;
    uint32_t uid;
    errno_t ret;

    /* Get fields. */
    upn = ldb_msg_find_attr_as_string(msg, SYSDB_UPN, NULL);
    name = sss_get_name_from_msg(domain, msg);
    gid = nss_get_gid(domain, msg);
    uid = sss_view_ldb_msg_find_attr_as_uint64(domain, msg, SYSDB_UIDNUM, 0);

    if (name == NULL || uid == 0 || gid == 0) {
        DEBUG(SSSDBG_OP_FAILURE,
              "Incomplete user object for %s[%u]! Skipping\n",
              name ? name : "<NULL>", uid);
        return EINVAL;
    }

    gecos = sss_view_ldb_msg_find_attr_as_string(domain, msg, SYSDB_GECOS,
                                                 NULL);
    homedir = nss_get_homedir(mem_ctx, nss_ctx, domain, msg, name, upn, uid);
    ret = nss_get_shell(nss_ctx, domain, msg, name, uid, &shell);
    if (ret != EOK) {
        DEBUG(SSSDBG_CRIT_FAILURE,
              "failed retrieving shell for %s[%u], skipping [%d]: %s\n",
              name, uid, ret, sss_strerror(ret));
        return ret;
    }

    /* Convert to sized strings. */
    ret = sized_output_name(mem_ctx, nss_ctx->rctx, name, domain, _name);
    if (ret != EOK) {
        DEBUG(SSSDBG_CRIT_FAILURE,
              "sized_output_name failed, skipping [%d]: %s\n",
              ret, sss_strerror(ret));
        return ret;
    }

    to_sized_string(_gecos, gecos == NULL ? "" : gecos);
    to_sized_string(_shell, shell);
    to_sized_string(_homedir, homedir);

    *_gid = gid;
    *_uid = uid;

    return EOK;
}
Exemple #4
0
static errno_t sudosrv_get_user(struct sudo_dom_ctx *dctx)
{
    TALLOC_CTX *tmp_ctx = NULL;
    struct sss_domain_info *dom = dctx->domain;
    struct sudo_cmd_ctx *cmd_ctx = dctx->cmd_ctx;
    struct cli_ctx *cli_ctx = dctx->cmd_ctx->cli_ctx;
    struct ldb_result *user;
    time_t cache_expire = 0;
    struct tevent_req *dpreq;
    struct dp_callback_ctx *cb_ctx;
    const char *original_name = NULL;
    const char *extra_flag = NULL;
    char *name = NULL;
    uid_t uid = 0;
    errno_t ret;

    tmp_ctx = talloc_new(NULL);
    if (tmp_ctx == NULL) {
        DEBUG(SSSDBG_CRIT_FAILURE, "talloc_new() failed\n");
        return ENOMEM;
    }

    while (dom) {
       /* if it is a domainless search, skip domains that require fully
        * qualified names instead */
        while (dom && cmd_ctx->check_next && dom->fqnames) {
            dom = get_next_domain(dom, false);
        }

        if (!dom) break;

        /* make sure to update the dctx if we changed domain */
        dctx->domain = dom;

        talloc_free(name);
        name = sss_get_cased_name(tmp_ctx, cmd_ctx->username,
                                  dom->case_sensitive);
        if (name == NULL) {
            DEBUG(SSSDBG_CRIT_FAILURE, "Out of memory\n");
            ret = ENOMEM;
            goto done;
        }

        name = sss_reverse_replace_space(tmp_ctx, name,
                                         cmd_ctx->sudo_ctx->rctx->override_space);
        if (name == NULL) {
            DEBUG(SSSDBG_CRIT_FAILURE,
                  "sss_reverse_replace_whitespaces failed\n");
            return ENOMEM;
        }

        DEBUG(SSSDBG_FUNC_DATA, "Requesting info about [%s@%s]\n",
              name, dom->name);

        ret = sysdb_getpwnam_with_views(dctx, dctx->domain, name, &user);
        if (ret != EOK) {
            DEBUG(SSSDBG_OP_FAILURE,
                  "Failed to make request to our cache!\n");
            ret = EIO;
            goto done;
        }

        if (user->count > 1) {
            DEBUG(SSSDBG_CRIT_FAILURE,
                  "getpwnam call returned more than one result !?!\n");
            ret = EIO;
            goto done;
        }

        if (user->count == 0 && !dctx->check_provider) {
            /* if a multidomain search, try with next */
            if (cmd_ctx->check_next) {
                dctx->check_provider = true;
                dom = get_next_domain(dom, false);
                if (dom) continue;
            }

            DEBUG(SSSDBG_MINOR_FAILURE, "No results for getpwnam call\n");
            ret = ENOENT;
            goto done;
        }

        /* One result found, check cache expiry */
        if (user->count == 1) {
            cache_expire = ldb_msg_find_attr_as_uint64(user->msgs[0],
                                                       SYSDB_CACHE_EXPIRE, 0);
        }

        /* If cache miss and we haven't checked DP yet OR the entry is
         * outdated, go to DP */
        if ((user->count == 0 || cache_expire < time(NULL))
            && dctx->check_provider) {

            if (DOM_HAS_VIEWS(dom) && user->count == 0) {
                extra_flag = EXTRA_INPUT_MAYBE_WITH_VIEW;
            }

            dpreq = sss_dp_get_account_send(cli_ctx, cli_ctx->rctx,
                                            dom, false, SSS_DP_INITGROUPS,
                                            cmd_ctx->username, 0, extra_flag);
            if (!dpreq) {
                DEBUG(SSSDBG_CRIT_FAILURE,
                      "Out of memory sending data provider request\n");
                ret = ENOMEM;
                goto done;
            }

            cb_ctx = talloc_zero(cli_ctx, struct dp_callback_ctx);
            if(!cb_ctx) {
                talloc_zfree(dpreq);
                ret = ENOMEM;
                goto done;
            }

            cb_ctx->callback = sudosrv_check_user_dp_callback;
            cb_ctx->ptr = dctx;
            cb_ctx->cctx = cli_ctx;
            cb_ctx->mem_ctx = cli_ctx;

            tevent_req_set_callback(dpreq, sudosrv_dp_send_acct_req_done, cb_ctx);

            /* tell caller we are in an async call */
            ret = EAGAIN;
            goto done;
        }

        /* check uid */
        uid = sss_view_ldb_msg_find_attr_as_uint64(dom, user->msgs[0],
                                                   SYSDB_UIDNUM, 0);
        if (uid != cmd_ctx->uid) {
            /* if a multidomain search, try with next */
            if (cmd_ctx->check_next) {
                dctx->check_provider = true;
                dom = get_next_domain(dom, false);
                if (dom) continue;
            }

            DEBUG(SSSDBG_MINOR_FAILURE, "UID does not match\n");
            ret = ENOENT;
            goto done;
        }

        /* user is stored in cache, remember cased and original name */
        original_name = ldb_msg_find_attr_as_string(user->msgs[0],
                                                    SYSDB_NAME, NULL);
        if (original_name == NULL) {
            DEBUG(SSSDBG_CRIT_FAILURE, "A user with no name?\n");
            ret = EFAULT;
            goto done;
        }

        cmd_ctx->cased_username = talloc_move(cmd_ctx, &name);
        cmd_ctx->orig_username = talloc_strdup(cmd_ctx, original_name);
        if (cmd_ctx->orig_username == NULL) {
            DEBUG(SSSDBG_CRIT_FAILURE, "Out of memory\n");
            ret = ENOMEM;
            goto done;
        }

        /* and set domain */
        cmd_ctx->domain = dom;

        DEBUG(SSSDBG_TRACE_FUNC, "Returning info for user [%s@%s]\n",
              cmd_ctx->username, dctx->domain->name);
        ret = EOK;
        goto done;
    }

    ret = ENOENT;
done:
    talloc_free(tmp_ctx);
    return ret;
}