summaryrefslogtreecommitdiffstats
path: root/src/responder
diff options
context:
space:
mode:
authorSumit Bose <sbose@redhat.com>2013-11-07 11:09:35 +0100
committerJakub Hrozek <jhrozek@redhat.com>2013-11-15 20:38:08 +0100
commit36c266d467e9105041b33e9b1cdcd9ff073d893e (patch)
treedaab56fb42c446f8103cd1aabd2f4495f1e347d6 /src/responder
parent32b976eb666044d106dd85e27f8d0bb1d7b6cd6c (diff)
downloadsssd-36c266d467e9105041b33e9b1cdcd9ff073d893e.tar.gz
sssd-36c266d467e9105041b33e9b1cdcd9ff073d893e.tar.xz
sssd-36c266d467e9105041b33e9b1cdcd9ff073d893e.zip
nss: check for Well-Known SIDs in SID based requests
Diffstat (limited to 'src/responder')
-rw-r--r--src/responder/nss/nsssrv_cmd.c134
1 files changed, 134 insertions, 0 deletions
diff --git a/src/responder/nss/nsssrv_cmd.c b/src/responder/nss/nsssrv_cmd.c
index d9fc7155b..64bb9bc9f 100644
--- a/src/responder/nss/nsssrv_cmd.c
+++ b/src/responder/nss/nsssrv_cmd.c
@@ -973,6 +973,57 @@ done:
}
}
+static int nss_check_name_of_well_known_sid(struct nss_cmd_ctx *cmdctx,
+ const char *full_name)
+{
+ char *wk_name = NULL;
+ char *wk_dom_name = NULL;
+ const char *wk_sid;
+ int ret;
+ struct sized_string sid;
+ uint8_t *body;
+ size_t blen;
+ struct cli_ctx *cctx;
+ struct nss_ctx *nss_ctx;
+
+ nss_ctx = talloc_get_type(cmdctx->cctx->rctx->pvt_ctx, struct nss_ctx);
+ ret = sss_parse_name(cmdctx, nss_ctx->global_names, full_name,
+ &wk_dom_name, &wk_name);
+ if (ret != EOK) {
+ DEBUG(SSSDBG_OP_FAILURE, ("sss_parse_name failed.\n"));
+ return ret;
+ }
+
+ ret = name_to_well_known_sid(wk_dom_name, wk_name, &wk_sid);
+ talloc_free(wk_dom_name);
+ talloc_free(wk_name);
+ if (ret != EOK) {
+ DEBUG(SSSDBG_TRACE_ALL, ("Name [%s] is not the name of a " \
+ "Well-Known SID.\n", full_name));
+ return ret;
+ }
+
+ to_sized_string(&sid, wk_sid);
+
+ cctx = cmdctx->cctx;
+ ret = sss_packet_new(cctx->creq, sid.len + 3 * sizeof(uint32_t),
+ sss_packet_get_cmd(cctx->creq->in),
+ &cctx->creq->out);
+ if (ret != EOK) {
+ return ENOMEM;
+ }
+
+ sss_packet_get_body(cctx->creq->out, &body, &blen);
+ ((uint32_t *)body)[0] = 1; /* num results */
+ ((uint32_t *)body)[1] = 0; /* reserved */
+ ((uint32_t *)body)[2] = (uint32_t) SSS_ID_TYPE_GID;
+ memcpy(&body[3*sizeof(uint32_t)], sid.str, sid.len);
+
+ sss_packet_set_error(cctx->creq->out, EOK);
+ sss_cmd_done(cctx, cmdctx);
+ return EOK;
+}
+
static int nss_cmd_getbynam(enum sss_cli_command cmd, struct cli_ctx *cctx);
static void nss_cmd_getbynam_done(struct tevent_req *req);
static int nss_cmd_getpwnam(struct cli_ctx *cctx)
@@ -1037,6 +1088,20 @@ static int nss_cmd_getbynam(enum sss_cli_command cmd, struct cli_ctx *cctx)
DEBUG(SSSDBG_TRACE_FUNC, ("Running command [%d] with input [%s].\n",
dctx->cmdctx->cmd, rawname));
+ if (dctx->cmdctx->cmd == SSS_NSS_GETSIDBYNAME) {
+ ret = nss_check_name_of_well_known_sid(cmdctx, rawname);
+ if (ret != ENOENT) {
+ if (ret == EOK) {
+ DEBUG(SSSDBG_TRACE_ALL, ("Name [%s] is the name of a " \
+ "Well-Known SID.\n", rawname));
+ } else {
+ DEBUG(SSSDBG_OP_FAILURE,
+ ("nss_check_name_of_well_known_sid failed.\n"));
+ }
+ goto done;
+ }
+ }
+
/* We need to attach to subdomain request, if the first one is not
* finished yet. We may not be able to lookup object in AD otherwise. */
if (cctx->rctx->get_domains_last_call.tv_sec == 0) {
@@ -4278,6 +4343,64 @@ static errno_t nss_cmd_getbysid_send_reply(struct nss_dom_ctx *dctx)
return EOK;
}
+static int nss_check_well_known_sid(struct nss_cmd_ctx *cmdctx)
+{
+ const char *wk_name;
+ const char *wk_dom_name;
+ int ret;
+ char *fq_name = NULL;
+ struct sized_string name;
+ uint8_t *body;
+ size_t blen;
+ struct cli_ctx *cctx;
+ struct nss_ctx *nss_ctx;
+
+ ret = well_known_sid_to_name(cmdctx->secid, &wk_dom_name, &wk_name);
+ if (ret != EOK) {
+ DEBUG(SSSDBG_TRACE_ALL, ("SID [%s] is not a Well-Known SID.\n",
+ cmdctx->secid));
+ return ret;
+ }
+
+ if (cmdctx->cmd != SSS_NSS_GETNAMEBYSID) {
+ DEBUG(SSSDBG_TRACE_ALL,
+ ("Well-Known SIDs can only be translated to names.\n"));
+ return EINVAL;
+ }
+
+ if (wk_dom_name != NULL) {
+ nss_ctx = talloc_get_type(cmdctx->cctx->rctx->pvt_ctx, struct nss_ctx);
+ fq_name = sss_tc_fqname2(cmdctx, nss_ctx->global_names,
+ wk_dom_name, wk_dom_name, wk_name);
+ if (fq_name == NULL) {
+ DEBUG(SSSDBG_OP_FAILURE, ("sss_tc_fqname2 failed.\n"));
+ return ENOMEM;
+ }
+ to_sized_string(&name, fq_name);
+ } else {
+ to_sized_string(&name, wk_name);
+ }
+
+ cctx = cmdctx->cctx;
+ ret = sss_packet_new(cctx->creq, name.len + 3 * sizeof(uint32_t),
+ sss_packet_get_cmd(cctx->creq->in),
+ &cctx->creq->out);
+ if (ret != EOK) {
+ talloc_free(fq_name);
+ return ENOMEM;
+ }
+
+ sss_packet_get_body(cctx->creq->out, &body, &blen);
+ ((uint32_t *)body)[0] = 1; /* num results */
+ ((uint32_t *)body)[1] = 0; /* reserved */
+ ((uint32_t *)body)[2] = (uint32_t) SSS_ID_TYPE_GID;
+ memcpy(&body[3*sizeof(uint32_t)], name.str, name.len);
+
+ sss_packet_set_error(cctx->creq->out, EOK);
+ sss_cmd_done(cctx, cmdctx);
+ return EOK;
+}
+
static int nss_cmd_getbysid(enum sss_cli_command cmd, struct cli_ctx *cctx)
{
@@ -4346,6 +4469,17 @@ static int nss_cmd_getbysid(enum sss_cli_command cmd, struct cli_ctx *cctx)
goto done;
}
+ ret = nss_check_well_known_sid(cmdctx);
+ if (ret != ENOENT) {
+ if (ret == EOK) {
+ DEBUG(SSSDBG_TRACE_ALL, ("SID [%s] is a Well-Known SID.\n",
+ cmdctx->secid));
+ } else {
+ DEBUG(SSSDBG_OP_FAILURE, ("nss_check_well_known_sid failed.\n"));
+ }
+ goto done;
+ }
+
ret = responder_get_domain_by_id(cctx->rctx, cmdctx->secid, &dctx->domain);
if (ret == EAGAIN || ret == ENOENT) {
req = sss_dp_get_domains_send(cctx->rctx, cctx->rctx, true, NULL);