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); }
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; }