>From b81e7a2ec0d1b693b9d5cb30d40bbcb57bc8654e Mon Sep 17 00:00:00 2001
From: George McCollister <georgem@novatech-llc.com>
Date: Mon, 1 Mar 2010 09:47:24 -0600
Subject: [PATCH] Fixed alignment problems in nss client/server

I fixed a handful of alignment problems in sss_client and nss responder. Enumerating group and passwd with getgrent and getpwent now works correctly on ARM.

Signed-off-by: George McCollister <georgem@novatech-llc.com>
---
 src/responder/nss/nsssrv_cmd.c |   14 +++++++++-----
 src/sss_client/group.c         |   18 +++++++++++++-----
 src/sss_client/passwd.c        |    7 +++++--
 3 files changed, 27 insertions(+), 12 deletions(-)

diff --git a/src/responder/nss/nsssrv_cmd.c b/src/responder/nss/nsssrv_cmd.c
index 46d4a23..0e89618 100644
--- a/src/responder/nss/nsssrv_cmd.c
+++ b/src/responder/nss/nsssrv_cmd.c
@@ -205,8 +205,8 @@ static int fill_pwent(struct sss_packet *packet,
         }
         sss_packet_get_body(packet, &body, &blen);
 
-        ((uint32_t *)(&body[rp]))[0] = uid;
-        ((uint32_t *)(&body[rp]))[1] = gid;
+        memcpy(&body[rp], &uid, sizeof(uint32_t));
+        memcpy(&body[rp+sizeof(uint32_t)], &gid, sizeof(uint32_t));
         rp += 2*sizeof(uint32_t);
 
         if (add_domain) {
@@ -1480,6 +1480,7 @@ static int fill_grent(struct sss_packet *packet,
     uint8_t *body;
     size_t blen;
     uint32_t gid;
+    uint32_t c;
     const char *name;
     size_t nsize;
     size_t delim;
@@ -1566,10 +1567,12 @@ static int fill_grent(struct sss_packet *packet,
         sss_packet_get_body(packet, &body, &blen);
 
         /*  0-3: 32bit number gid */
-        ((uint32_t *)(&body[rzero+GID_ROFFSET]))[0] = gid;
+        c = gid;
+        memcpy(&body[rzero+GID_ROFFSET], &c, sizeof(uint32_t));
 
         /*  4-7: 32bit unsigned number of members */
-        ((uint32_t *)(&body[rzero+MNUM_ROFFSET]))[0] = 0;
+        c = 0;
+        memcpy(&body[rzero+MNUM_ROFFSET], &c, sizeof(uint32_t));
 
         /*  8-X: sequence of strings (name, passwd, mem..) */
         if (add_domain) {
@@ -1688,7 +1691,8 @@ static int fill_grent(struct sss_packet *packet,
 
             if (memnum) {
                 /* set num of members */
-                ((uint32_t *)(&body[rzero+MNUM_ROFFSET]))[0] = memnum;
+                c = memnum;
+		memcpy(&body[rzero+MNUM_ROFFSET], &c, sizeof(uint32_t));
             }
         }
 
diff --git a/src/sss_client/group.c b/src/sss_client/group.c
index 675b8b7..7c624ab 100644
--- a/src/sss_client/group.c
+++ b/src/sss_client/group.c
@@ -78,17 +78,19 @@ struct sss_nss_gr_rep {
 static int sss_nss_getgr_readrep(struct sss_nss_gr_rep *pr,
                                  uint8_t *buf, size_t *len)
 {
-    size_t i, l, slen, ptmem;
+    size_t i, l, slen, ptmem, pad;
     ssize_t dlen;
     char *sbuf;
     uint32_t mem_num;
+    uint32_t c;
 
     if (*len < 11) { /* not enough space for data, bad packet */
         return EBADMSG;
     }
 
-    pr->result->gr_gid = ((uint32_t *)buf)[0];
-    mem_num = ((uint32_t *)buf)[1];
+    memcpy(&c, buf, sizeof(uint32_t));
+    pr->result->gr_gid = c;
+    memcpy(&mem_num, buf+sizeof(uint32_t), sizeof(uint32_t));
 
     sbuf = (char *)&buf[8];
     slen = *len - 8;
@@ -127,9 +129,15 @@ static int sss_nss_getgr_readrep(struct sss_nss_gr_rep *pr,
     i++;
     dlen--;
 
+    /* Make sure pr->buffer[i+pad] is 32 bit aligned */
+    pad = 0;
+    while((i + pad) % 4) {
+        pad++;
+    }
+
     /* now members */
-    pr->result->gr_mem = (char **)&(pr->buffer[i]);
-    ptmem = sizeof(char *) * (mem_num + 1);
+    pr->result->gr_mem = (char **)&(pr->buffer[i+pad]);
+    ptmem = (sizeof(char *) * (mem_num + 1)) + pad;
     if (ptmem > dlen) {
         return ERANGE; /* not ENOMEM, ERANGE is what glibc looks for */
     }
diff --git a/src/sss_client/passwd.c b/src/sss_client/passwd.c
index 0d70b68..7b038a6 100644
--- a/src/sss_client/passwd.c
+++ b/src/sss_client/passwd.c
@@ -74,13 +74,16 @@ static int sss_nss_getpw_readrep(struct sss_nss_pw_rep *pr,
 {
     size_t i, slen, dlen;
     char *sbuf;
+    uint32_t c;
 
     if (*len < 13) { /* not enough space for data, bad packet */
         return EBADMSG;
     }
 
-    pr->result->pw_uid = ((uint32_t *)buf)[0];
-    pr->result->pw_gid = ((uint32_t *)buf)[1];
+    memcpy(&c, buf, sizeof(uint32_t));
+    pr->result->pw_uid = c;
+    memcpy(&c, buf+sizeof(uint32_t), sizeof(uint32_t));
+    pr->result->pw_gid = c;
 
     sbuf = (char *)&buf[8];
     slen = *len - 8;
-- 
1.6.4.2

