Esempio n. 1
0
static int get_pw_uid(TALLOC_CTX *mem_ctx,
                      struct proxy_id_ctx *ctx,
                      struct sysdb_ctx *sysdb,
                      struct sss_domain_info *dom,
                      uid_t uid)
{
    TALLOC_CTX *tmpctx;
    struct passwd *pwd;
    enum nss_status status;
    char *buffer;
    size_t buflen;
    bool del_user = false;
    int ret;

    DEBUG(SSSDBG_TRACE_FUNC, ("Searching user by uid (%d)\n", uid));

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

    pwd = talloc_zero(tmpctx, struct passwd);
    if (!pwd) {
        ret = ENOMEM;
        goto done;
    }

    buflen = DEFAULT_BUFSIZE;
    buffer = talloc_size(tmpctx, buflen);
    if (!buffer) {
        ret = ENOMEM;
        goto done;
    }

    status = ctx->ops.getpwuid_r(uid, pwd, buffer, buflen, &ret);
    ret = handle_getpw_result(status, pwd, dom, &del_user);
    if (ret) {
        DEBUG(SSSDBG_OP_FAILURE,
              ("getpwuid failed [%d]: %s\n", ret, strerror(ret)));
        goto done;
    }

    if (del_user) {
        ret = delete_user(sysdb, dom, NULL, uid);
        goto done;
    }

    ret = save_user(sysdb, dom, !dom->case_sensitive, pwd,
                    pwd->pw_name, NULL, dom->user_timeout);

done:
    talloc_zfree(tmpctx);
    if (ret) {
        DEBUG(SSSDBG_CRIT_FAILURE,
              ("proxy -> getpwuid_r failed for '%d' <%d>: %s\n",
               uid, ret, strerror(ret)));
    }
    return ret;
}
Esempio n. 2
0
static int get_pw_name(struct proxy_id_ctx *ctx,
                       struct sss_domain_info *dom,
                       const char *name)
{
    TALLOC_CTX *tmpctx;
    struct passwd *pwd;
    enum nss_status status;
    char *buffer;
    size_t buflen;
    int ret;
    uid_t uid;
    bool del_user;
    struct ldb_result *cached_pwd = NULL;
    const char *real_name = NULL;

    DEBUG(SSSDBG_TRACE_FUNC, "Searching user by name (%s)\n", name);

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

    pwd = talloc_zero(tmpctx, struct passwd);
    if (!pwd) {
        ret = ENOMEM;
        goto done;
    }

    buflen = DEFAULT_BUFSIZE;
    buffer = talloc_size(tmpctx, buflen);
    if (!buffer) {
        ret = ENOMEM;
        goto done;
    }

    /* FIXME: should we move this call outside the transaction to keep the
     * transaction as short as possible ? */
    status = ctx->ops.getpwnam_r(name, pwd, buffer, buflen, &ret);
    ret = handle_getpw_result(status, pwd, dom, &del_user);
    if (ret) {
        DEBUG(SSSDBG_OP_FAILURE,
              "getpwnam failed [%d]: %s\n", ret, strerror(ret));
        goto done;
    }

    if (del_user) {
        ret = delete_user(dom, name, 0);
        goto done;
    }

    uid = pwd->pw_uid;

    /* Canonicalize the username in case it was actually an alias */

    if (ctx->fast_alias == true) {
        ret = sysdb_getpwuid(tmpctx, dom, uid, &cached_pwd);
        if (ret != EOK) {
            /* Non-fatal, attempt to canonicalize online */
            DEBUG(SSSDBG_TRACE_FUNC, "Request to cache failed [%d]: %s\n",
                  ret, strerror(ret));
        }

        if (ret == EOK && cached_pwd->count == 1) {
            real_name = ldb_msg_find_attr_as_string(cached_pwd->msgs[0],
                                                    SYSDB_NAME, NULL);
            if (!real_name) {
                DEBUG(SSSDBG_MINOR_FAILURE, "Cached user has no name?\n");
            }
        }
    }

    if (real_name == NULL) {
        memset(buffer, 0, buflen);

        status = ctx->ops.getpwuid_r(uid, pwd, buffer, buflen, &ret);
        ret = handle_getpw_result(status, pwd, dom, &del_user);
        if (ret) {
            DEBUG(SSSDBG_OP_FAILURE,
                  "getpwuid failed [%d]: %s\n", ret, strerror(ret));
            goto done;
        }

        real_name = pwd->pw_name;
    }

    if (del_user) {
        ret = delete_user(dom, name, uid);
        goto done;
    }

    /* Both lookups went fine, we can save the user now */
    ret = save_user(dom, !dom->case_sensitive, pwd,
                    real_name, name, dom->user_timeout);

done:
    talloc_zfree(tmpctx);
    if (ret) {
        DEBUG(SSSDBG_OP_FAILURE,
              "proxy -> getpwnam_r failed for '%s' <%d>: %s\n",
              name, ret, strerror(ret));
    }
    return ret;
}
Esempio n. 3
0
static int get_initgr(TALLOC_CTX *mem_ctx,
                      struct proxy_id_ctx *ctx,
                      struct sysdb_ctx *sysdb,
                      struct sss_domain_info *dom,
                      const char *name)
{
    TALLOC_CTX *tmpctx;
    bool in_transaction = false;
    struct passwd *pwd;
    enum nss_status status;
    char *buffer;
    size_t buflen;
    int ret;
    errno_t sret;
    bool del_user;
    uid_t uid;
    struct ldb_result *cached_pwd = NULL;
    const char *real_name = NULL;

    tmpctx = talloc_new(mem_ctx);
    if (!tmpctx) {
        return ENOMEM;
    }

    pwd = talloc_zero(tmpctx, struct passwd);
    if (!pwd) {
        ret = ENOMEM;
        goto fail;
    }

    buflen = DEFAULT_BUFSIZE;
    buffer = talloc_size(tmpctx, buflen);
    if (!buffer) {
        ret = ENOMEM;
        goto fail;
    }

    ret = sysdb_transaction_start(sysdb);
    if (ret) {
        DEBUG(SSSDBG_CRIT_FAILURE, "Failed to start transaction\n");
        goto fail;
    }
    in_transaction = true;

    /* FIXME: should we move this call outside the transaction to keep the
     * transaction as short as possible ? */
    status = ctx->ops.getpwnam_r(name, pwd, buffer, buflen, &ret);
    ret = handle_getpw_result(status, pwd, dom, &del_user);
    if (ret) {
        DEBUG(SSSDBG_OP_FAILURE,
              "getpwnam failed [%d]: %s\n", ret, strerror(ret));
        goto fail;
    }

    if (del_user) {
        ret = delete_user(dom, name, 0);
        if (ret) {
            DEBUG(SSSDBG_OP_FAILURE, "Could not delete user\n");
            goto fail;
        }
        goto done;
    }

    uid = pwd->pw_uid;
    memset(buffer, 0, buflen);

    /* Canonicalize the username in case it was actually an alias */
    if (ctx->fast_alias == true) {
        ret = sysdb_getpwuid(tmpctx, dom, uid, &cached_pwd);
        if (ret != EOK) {
            /* Non-fatal, attempt to canonicalize online */
            DEBUG(SSSDBG_TRACE_FUNC, "Request to cache failed [%d]: %s\n",
                  ret, strerror(ret));
        }

        if (ret == EOK && cached_pwd->count == 1) {
            real_name = ldb_msg_find_attr_as_string(cached_pwd->msgs[0],
                                                    SYSDB_NAME, NULL);
            if (!real_name) {
                DEBUG(SSSDBG_MINOR_FAILURE, "Cached user has no name?\n");
            }
        }
    }

    if (real_name == NULL) {
        memset(buffer, 0, buflen);

        status = ctx->ops.getpwuid_r(uid, pwd, buffer, buflen, &ret);
        ret = handle_getpw_result(status, pwd, dom, &del_user);
        if (ret) {
            DEBUG(SSSDBG_OP_FAILURE,
                  "getpwuid failed [%d]: %s\n", ret, strerror(ret));
            goto done;
        }

        real_name = pwd->pw_name;
    }

    if (del_user) {
        ret = delete_user(dom, name, uid);
        if (ret) {
            DEBUG(SSSDBG_OP_FAILURE, "Could not delete user\n");
            goto fail;
        }
        goto done;
    }

    ret = save_user(dom, !dom->case_sensitive, pwd,
                    real_name, name, dom->user_timeout);
    if (ret) {
        DEBUG(SSSDBG_OP_FAILURE, "Could not save user\n");
        goto fail;
    }

    ret = get_initgr_groups_process(tmpctx, ctx, sysdb, dom, pwd);
    if (ret != EOK) {
        DEBUG(SSSDBG_OP_FAILURE, "Could not process initgroups\n");
        goto fail;
    }

done:
    ret = sysdb_transaction_commit(sysdb);
    if (ret) {
        DEBUG(SSSDBG_OP_FAILURE, "Failed to commit transaction\n");
        goto fail;
    }
    in_transaction = false;

fail:
    talloc_zfree(tmpctx);
    if (in_transaction) {
        sret = sysdb_transaction_cancel(sysdb);
        if (sret != EOK) {
            DEBUG(SSSDBG_CRIT_FAILURE, "Failed to cancel transaction\n");
        }
    }
    return ret;
}
Esempio n. 4
0
static int get_pw_uid(struct proxy_id_ctx *ctx,
                      struct sss_domain_info *dom,
                      uid_t uid)
{
    TALLOC_CTX *tmpctx;
    struct passwd *pwd;
    enum nss_status status;
    char *buffer;
    size_t buflen;
    bool del_user = false;
    int ret;
    char *name;

    DEBUG(SSSDBG_TRACE_FUNC, "Searching user by uid (%"SPRIuid")\n", uid);

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

    pwd = talloc_zero(tmpctx, struct passwd);
    if (!pwd) {
        ret = ENOMEM;
        goto done;
    }

    buflen = DEFAULT_BUFSIZE;
    buffer = talloc_size(tmpctx, buflen);
    if (!buffer) {
        ret = ENOMEM;
        goto done;
    }

    status = ctx->ops.getpwuid_r(uid, pwd, buffer, buflen, &ret);
    ret = handle_getpw_result(status, pwd, dom, &del_user);
    if (ret) {
        DEBUG(SSSDBG_OP_FAILURE,
              "getpwuid failed [%d]: %s\n", ret, strerror(ret));
        goto done;
    }

    if (del_user) {
        ret = delete_user(dom, NULL, uid);
        goto done;
    }

    name = sss_create_internal_fqname(tmpctx, pwd->pw_name, dom->name);
    if (name == NULL) {
        DEBUG(SSSDBG_OP_FAILURE, "failed to qualify name '%s'\n",
              pwd->pw_name);
        goto done;
    }
    ret = save_user(dom, pwd, name, NULL);

done:
    talloc_zfree(tmpctx);
    if (ret) {
        DEBUG(SSSDBG_CRIT_FAILURE,
              "proxy -> getpwuid_r failed for '%"SPRIuid"' <%d>: %s\n",
               uid, ret, strerror(ret));
    }
    return ret;
}