diff options
Diffstat (limited to 'server')
-rw-r--r-- | server/nss/nsssrv_cmd.c | 135 |
1 files changed, 75 insertions, 60 deletions
diff --git a/server/nss/nsssrv_cmd.c b/server/nss/nsssrv_cmd.c index a14004878..8e15bcf52 100644 --- a/server/nss/nsssrv_cmd.c +++ b/server/nss/nsssrv_cmd.c @@ -57,11 +57,10 @@ static int nss_cmd_get_version(struct cli_ctx *cctx) return RES_SUCCESS; } -static int nss_cmd_getpwnam_callback(void *ptr, int status, - struct ldb_result *res) +static int fill_pwent(struct nss_packet *packet, + struct ldb_message **msgs, + int count) { - struct nss_cmd_ctx *nctx = talloc_get_type(ptr, struct nss_cmd_ctx); - struct cli_ctx *cctx = nctx->cctx; struct ldb_message *msg; uint8_t *body; const char *name; @@ -70,7 +69,75 @@ static int nss_cmd_getpwnam_callback(void *ptr, int status, const char *shell; uint64_t uid; uint64_t gid; - size_t rsize, rp, rl, blen; + size_t rsize, rp, blen; + size_t s1, s2, s3, s4; + int i, ret, num = 0; + + /* first 2 fieldss (len and reserved), filled up later */ + ret = nss_packet_grow(packet, 2*sizeof(uint32_t)); + rp = 2*sizeof(uint32_t); + + for (i = 0; i < count; i++) { + msg = msgs[i]; + + name = ldb_msg_find_attr_as_string(msg, NSS_PW_NAME, NULL); + fullname = ldb_msg_find_attr_as_string(msg, NSS_PW_FULLNAME, NULL); + homedir = ldb_msg_find_attr_as_string(msg, NSS_PW_HOMEDIR, NULL); + shell = ldb_msg_find_attr_as_string(msg, NSS_PW_SHELL, NULL); + uid = ldb_msg_find_attr_as_uint64(msg, NSS_PW_UIDNUM, 0); + gid = ldb_msg_find_attr_as_uint64(msg, NSS_PW_GIDNUM, 0); + + if (!name || !fullname || !homedir || !shell || !uid || !gid) { + DEBUG(1, ("Incomplede user object for %s! Skipping\n", + name?name:"<NULL>")); + continue; + } + + s1 = strlen(name) + 1; + s2 = strlen(fullname) + 1; + s3 = strlen(homedir) + 1; + s4 = strlen(shell) + 1; + rsize = 2*sizeof(uint64_t) +s1 + 2 + s2 + s3 +s4; + + ret = nss_packet_grow(packet, rsize); + if (ret != RES_SUCCESS) { + num = 0; + goto done; + } + nss_get_body(packet, &body, &blen); + + ((uint64_t *)(&body[rp]))[0] = uid; + ((uint64_t *)(&body[rp]))[1] = gid; + rp += 2*sizeof(uint64_t); + memcpy(&body[rp], name, s1); + rp += s1; + memcpy(&body[rp], "x", 2); + rp += 2; + memcpy(&body[rp], fullname, s2); + rp += s2; + memcpy(&body[rp], homedir, s3); + rp += s3; + memcpy(&body[rp], shell, s4); + rp += s4; + + num++; + } + +done: + nss_get_body(packet, &body, &blen); + ((uint32_t *)body)[0] = num; /* num results */ + ((uint32_t *)body)[1] = 0; /* reserved */ + + return RES_SUCCESS; +} + +static int nss_cmd_getpwnam_callback(void *ptr, int status, + struct ldb_result *res) +{ + struct nss_cmd_ctx *nctx = talloc_get_type(ptr, struct nss_cmd_ctx); + struct cli_ctx *cctx = nctx->cctx; + uint8_t *body; + size_t blen; int ret; if (res->count != 1) { @@ -92,67 +159,15 @@ static int nss_cmd_getpwnam_callback(void *ptr, int status, goto done; } - msg = res->msgs[0]; - - name = ldb_msg_find_attr_as_string(msg, NSS_PW_NAME, NULL); - fullname = ldb_msg_find_attr_as_string(msg, NSS_PW_FULLNAME, NULL); - homedir = ldb_msg_find_attr_as_string(msg, NSS_PW_HOMEDIR, NULL); - shell = ldb_msg_find_attr_as_string(msg, NSS_PW_SHELL, NULL); - uid = ldb_msg_find_attr_as_uint64(msg, NSS_PW_UIDNUM, 0); - gid = ldb_msg_find_attr_as_uint64(msg, NSS_PW_UIDNUM, 0); - - if (!name || !fullname || !homedir || !shell || !uid || !gid) { - DEBUG(1, ("Incomplede user object?!? Aborting\n")); - - ret = nss_packet_new(cctx->creq, 2*sizeof(uint32_t), - nss_get_cmd(cctx->creq->in), - &cctx->creq->out); - if (ret != RES_SUCCESS) { - return ret; - } - nss_get_body(cctx->creq->out, &body, &blen); - ((uint32_t *)body)[0] = 0; /* 0 results */ - ((uint32_t *)body)[1] = 0; /* reserved */ - goto done; - } - - rsize = 2*sizeof(uint32_t); - rsize += 2*sizeof(uint64_t); - rsize += strlen(name) + 1; - rsize += 2; /* password always set to 'x' */ - rsize += strlen(fullname) + 1; - rsize += strlen(homedir) + 1; - rsize += strlen(shell) + 1; - /* create response packet */ - ret = nss_packet_new(cctx->creq, rsize, + ret = nss_packet_new(cctx->creq, 0, nss_get_cmd(cctx->creq->in), &cctx->creq->out); if (ret != RES_SUCCESS) { return ret; } - nss_get_body(cctx->creq->out, &body, &blen); - ((uint32_t *)body)[0] = 1; /* 1 result */ - ((uint32_t *)body)[1] = 0; /* reserved */ - ((uint64_t *)body)[1] = uid; /* first result uid */ - ((uint64_t *)body)[2] = gid; /* first result gid */ - - rp = 2*sizeof(uint32_t) + 2*sizeof(uint64_t); - rl = strlen(name)+1; - memcpy(&body[rp], name, rl); - rp += rl; - rl = 2; - memcpy(&body[rp], "x", rl); - rp += rl; - rl = strlen(fullname)+1; - memcpy(&body[rp], fullname, rl); - rp += rl; - rl = strlen(homedir)+1; - memcpy(&body[rp], homedir, rl); - rp += rl; - rl = strlen(shell)+1; - memcpy(&body[rp], shell, rl); + ret = fill_pwent(cctx->creq->out, res->msgs, res->count); done: /* now that the packet is in place, unlock queue @@ -162,7 +177,7 @@ done: /* free all request related data through the talloc hierarchy */ talloc_free(nctx); - return RES_SUCCESS; + return ret; } static int nss_cmd_getpwnam(struct cli_ctx *cctx) |