summaryrefslogtreecommitdiffstats
path: root/server
diff options
context:
space:
mode:
Diffstat (limited to 'server')
-rw-r--r--server/nss/nsssrv_cmd.c135
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)