예제 #1
0
파일: proxy_id.c 프로젝트: abbra/sssd
void proxy_get_account_info(struct be_req *breq)
{
    struct be_ctx *be_ctx = be_req_get_be_ctx(breq);
    struct be_acct_req *ar;
    struct proxy_id_ctx *ctx;
    struct sysdb_ctx *sysdb;
    struct sss_domain_info *domain;
    uid_t uid;
    gid_t gid;
    int ret;
    char *endptr;

    ar = talloc_get_type(be_req_get_data(breq), struct be_acct_req);
    ctx = talloc_get_type(be_ctx->bet_info[BET_ID].pvt_bet_data,
                          struct proxy_id_ctx);
    sysdb = be_ctx->domain->sysdb;
    domain = be_ctx->domain;

    if (be_is_offline(be_ctx)) {
        return be_req_terminate(breq, DP_ERR_OFFLINE, EAGAIN, "Offline");
    }

    /* for now we support only core attrs */
    if (ar->attr_type != BE_ATTR_CORE) {
        return be_req_terminate(breq, DP_ERR_FATAL, EINVAL, "Invalid attr type");
    }

    /* proxy provider does not support security ID lookups */
    if (ar->filter_type == BE_FILTER_SECID) {
        return be_req_terminate(breq, DP_ERR_FATAL, ENOSYS,
                                "Invalid filter type");
    }

    switch (ar->entry_type & BE_REQ_TYPE_MASK) {
    case BE_REQ_USER: /* user */
        switch (ar->filter_type) {
        case BE_FILTER_ENUM:
            ret = enum_users(breq, ctx, sysdb, domain);
            break;

        case BE_FILTER_NAME:
            ret = get_pw_name(ctx, domain, ar->filter_value);
            break;

        case BE_FILTER_IDNUM:
            uid = (uid_t) strtouint32(ar->filter_value, &endptr, 10);
            if (errno || *endptr || (ar->filter_value == endptr)) {
                return be_req_terminate(breq, DP_ERR_FATAL,
                                        EINVAL, "Invalid attr type");
            }
            ret = get_pw_uid(ctx, domain, uid);
            break;
        default:
            return be_req_terminate(breq, DP_ERR_FATAL,
                                    EINVAL, "Invalid filter type");
        }
        break;

    case BE_REQ_GROUP: /* group */
        switch (ar->filter_type) {
        case BE_FILTER_ENUM:
            ret = enum_groups(breq, ctx, sysdb, domain);
            break;
        case BE_FILTER_NAME:
            ret = get_gr_name(ctx, sysdb, domain, ar->filter_value);
            break;
        case BE_FILTER_IDNUM:
            gid = (gid_t) strtouint32(ar->filter_value, &endptr, 10);
            if (errno || *endptr || (ar->filter_value == endptr)) {
                return be_req_terminate(breq, DP_ERR_FATAL,
                                        EINVAL, "Invalid attr type");
            }
            ret = get_gr_gid(breq, ctx, sysdb, domain, gid, 0);
            break;
        default:
            return be_req_terminate(breq, DP_ERR_FATAL,
                                    EINVAL, "Invalid filter type");
        }
        break;

    case BE_REQ_INITGROUPS: /* init groups for user */
        if (ar->filter_type != BE_FILTER_NAME) {
            return be_req_terminate(breq, DP_ERR_FATAL,
                                    EINVAL, "Invalid filter type");
        }
        if (ctx->ops.initgroups_dyn == NULL) {
            return be_req_terminate(breq, DP_ERR_FATAL,
                                    ENODEV, "Initgroups call not supported");
        }
        ret = get_initgr(breq, ctx, sysdb, domain, ar->filter_value);
        break;

    case BE_REQ_NETGROUP:
        if (ar->filter_type != BE_FILTER_NAME) {
            return be_req_terminate(breq, DP_ERR_FATAL,
                                    EINVAL, "Invalid filter type");
        }
        if (ctx->ops.setnetgrent == NULL || ctx->ops.getnetgrent_r == NULL ||
                ctx->ops.endnetgrent == NULL) {
            return be_req_terminate(breq, DP_ERR_FATAL,
                                    ENODEV, "Netgroups are not supported");
        }

        ret = get_netgroup(ctx, domain, ar->filter_value);
        break;

    case BE_REQ_SERVICES:
        switch (ar->filter_type) {
        case BE_FILTER_NAME:
            if (ctx->ops.getservbyname_r == NULL) {
                return be_req_terminate(breq, DP_ERR_FATAL,
                                        ENODEV, "Services are not supported");
            }
            ret = get_serv_byname(ctx, domain,
                                  ar->filter_value,
                                  ar->extra_value);
            break;
        case BE_FILTER_IDNUM:
            if (ctx->ops.getservbyport_r == NULL) {
                return be_req_terminate(breq, DP_ERR_FATAL,
                                        ENODEV, "Services are not supported");
            }
            ret = get_serv_byport(ctx, domain,
                                  ar->filter_value,
                                  ar->extra_value);
            break;
        case BE_FILTER_ENUM:
            if (!ctx->ops.setservent
                    || !ctx->ops.getservent_r
                    || !ctx->ops.endservent) {
                return be_req_terminate(breq, DP_ERR_FATAL,
                                        ENODEV, "Services are not supported");
            }
            ret = enum_services(ctx, sysdb, domain);
            break;
        default:
            return be_req_terminate(breq, DP_ERR_FATAL,
                                    EINVAL, "Invalid filter type");
        }
        break;

    default: /*fail*/
        return be_req_terminate(breq, DP_ERR_FATAL,
                                EINVAL, "Invalid request type");
    }

    if (ret) {
        if (ret == ENXIO) {
            DEBUG(SSSDBG_OP_FAILURE,
                  "proxy returned UNAVAIL error, going offline!\n");
            be_mark_offline(be_ctx);
        }
        be_req_terminate(breq, DP_ERR_FATAL, ret, NULL);
        return;
    }
    be_req_terminate(breq, DP_ERR_OK, EOK, NULL);
}
예제 #2
0
파일: proxy_id.c 프로젝트: celestian/sssd
static struct dp_reply_std
proxy_account_info(TALLOC_CTX *mem_ctx,
                   struct proxy_id_ctx *ctx,
                   struct dp_id_data *data,
                   struct be_ctx *be_ctx,
                   struct sss_domain_info *domain)
{
    struct dp_reply_std reply;
    struct sysdb_ctx *sysdb;
    uid_t uid;
    gid_t gid;
    errno_t ret;
    char *endptr;

    sysdb = domain->sysdb;

    /* For now we support only core attrs. */
    if (data->attr_type != BE_ATTR_CORE) {
        dp_reply_std_set(&reply, DP_ERR_FATAL, EINVAL, "Invalid attr type");
        return reply;
    }

    /* Proxy provider does not support security ID lookups. */
    if (data->filter_type == BE_FILTER_SECID) {
        dp_reply_std_set(&reply, DP_ERR_FATAL, ENOSYS,
                         "Security lookups are not supported");
        return reply;
    }

    switch (data->entry_type & BE_REQ_TYPE_MASK) {
    case BE_REQ_USER: /* user */
        switch (data->filter_type) {
        case BE_FILTER_ENUM:
            ret = enum_users(mem_ctx, ctx, sysdb, domain);
            break;

        case BE_FILTER_NAME:
            ret = get_pw_name(ctx, domain, data->filter_value);
            break;

        case BE_FILTER_IDNUM:
            uid = (uid_t) strtouint32(data->filter_value, &endptr, 10);
            if (errno || *endptr || (data->filter_value == endptr)) {
                dp_reply_std_set(&reply, DP_ERR_FATAL, EINVAL,
                                 "Invalid attr type");
                return reply;
            }
            ret = get_pw_uid(ctx, domain, uid);
            break;
        default:
            dp_reply_std_set(&reply, DP_ERR_FATAL, EINVAL,
                             "Invalid filter type");
            return reply;
        }
        break;

    case BE_REQ_GROUP: /* group */
        switch (data->filter_type) {
        case BE_FILTER_ENUM:
            ret = enum_groups(mem_ctx, ctx, sysdb, domain);
            break;
        case BE_FILTER_NAME:
            ret = get_gr_name(ctx, sysdb, domain, data->filter_value);
            break;
        case BE_FILTER_IDNUM:
            gid = (gid_t) strtouint32(data->filter_value, &endptr, 10);
            if (errno || *endptr || (data->filter_value == endptr)) {
                dp_reply_std_set(&reply, DP_ERR_FATAL, EINVAL,
                                 "Invalid attr type");
                return reply;
            }
            ret = get_gr_gid(mem_ctx, ctx, sysdb, domain, gid, 0);
            break;
        default:
            dp_reply_std_set(&reply, DP_ERR_FATAL, EINVAL,
                             "Invalid filter type");
            return reply;
        }
        break;

    case BE_REQ_INITGROUPS: /* init groups for user */
        if (data->filter_type != BE_FILTER_NAME) {
            dp_reply_std_set(&reply, DP_ERR_FATAL, EINVAL,
                             "Invalid filter type");
            return reply;
        }
        if (ctx->ops.initgroups_dyn == NULL) {
            dp_reply_std_set(&reply, DP_ERR_FATAL, ENODEV,
                             "Initgroups call not supported");
            return reply;
        }
        ret = get_initgr(mem_ctx, ctx, sysdb, domain, data->filter_value);
        break;

    case BE_REQ_NETGROUP:
        if (data->filter_type != BE_FILTER_NAME) {
            dp_reply_std_set(&reply, DP_ERR_FATAL, EINVAL,
                             "Invalid filter type");
            return reply;
        }
        if (ctx->ops.setnetgrent == NULL || ctx->ops.getnetgrent_r == NULL ||
            ctx->ops.endnetgrent == NULL) {
            dp_reply_std_set(&reply, DP_ERR_FATAL, ENODEV,
                             "Netgroups are not supported");
            return reply;
        }

        ret = get_netgroup(ctx, domain, data->filter_value);
        break;

    case BE_REQ_SERVICES:
        switch (data->filter_type) {
        case BE_FILTER_NAME:
            if (ctx->ops.getservbyname_r == NULL) {
                dp_reply_std_set(&reply, DP_ERR_FATAL, ENODEV,
                                 "Services are not supported");
                return reply;
            }
            ret = get_serv_byname(ctx, domain,
                                  data->filter_value,
                                  data->extra_value);
            break;
        case BE_FILTER_IDNUM:
            if (ctx->ops.getservbyport_r == NULL) {
                dp_reply_std_set(&reply, DP_ERR_FATAL, ENODEV,
                                 "Services are not supported");
                return reply;
            }
            ret = get_serv_byport(ctx, domain,
                                  data->filter_value,
                                  data->extra_value);
            break;
        case BE_FILTER_ENUM:
            if (!ctx->ops.setservent
                    || !ctx->ops.getservent_r
                    || !ctx->ops.endservent) {
                dp_reply_std_set(&reply, DP_ERR_FATAL, ENODEV,
                                 "Services are not supported");
                return reply;
            }
            ret = enum_services(ctx, sysdb, domain);
            break;
        default:
            dp_reply_std_set(&reply, DP_ERR_FATAL, EINVAL,
                             "Invalid filter type");
            return reply;
        }
        break;

    default: /*fail*/
        dp_reply_std_set(&reply, DP_ERR_FATAL, EINVAL,
                         "Invalid filter type");
        return reply;
    }

    if (ret) {
        if (ret == ENXIO) {
            DEBUG(SSSDBG_OP_FAILURE,
                  "proxy returned UNAVAIL error, going offline!\n");
            be_mark_offline(be_ctx);
        }

        dp_reply_std_set(&reply, DP_ERR_FATAL, ret, NULL);
        return reply;
    }

    dp_reply_std_set(&reply, DP_ERR_OK, EOK, NULL);
    return reply;
}