summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorGeorge McCollister <georgem@novatech-llc.com>2010-03-04 09:41:33 -0600
committerStephen Gallagher <sgallagh@redhat.com>2010-03-08 13:42:46 -0500
commit8ad7891f28c0ffd991c51f2d64c32cf04c9ddbbc (patch)
tree6e6e8d8a8ad4e6e4b185b1aeeff2fdce0d943b90
parent7d83d46ff9eb06b294c186a41ad9e7dbe648f5c3 (diff)
downloadsssd-8ad7891f28c0ffd991c51f2d64c32cf04c9ddbbc.tar.gz
sssd-8ad7891f28c0ffd991c51f2d64c32cf04c9ddbbc.tar.xz
sssd-8ad7891f28c0ffd991c51f2d64c32cf04c9ddbbc.zip
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>
-rw-r--r--src/responder/nss/nsssrv_cmd.c11
-rw-r--r--src/sss_client/group.c18
-rw-r--r--src/sss_client/passwd.c7
-rw-r--r--src/sss_client/sss_cli.h14
4 files changed, 37 insertions, 13 deletions
diff --git a/src/responder/nss/nsssrv_cmd.c b/src/responder/nss/nsssrv_cmd.c
index c43a544eb..042517ad8 100644
--- a/src/responder/nss/nsssrv_cmd.c
+++ b/src/responder/nss/nsssrv_cmd.c
@@ -205,9 +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;
- rp += 2*sizeof(uint32_t);
+ SAFEALIGN_SET_UINT32(&body[rp], uid, &rp);
+ SAFEALIGN_SET_UINT32(&body[rp], gid, &rp);
if (add_domain) {
ret = snprintf((char *)&body[rp], s1, namefmt, name, domain);
@@ -1566,10 +1565,10 @@ 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;
+ SAFEALIGN_SET_UINT32(&body[rzero+GID_ROFFSET], gid, NULL);
/* 4-7: 32bit unsigned number of members */
- ((uint32_t *)(&body[rzero+MNUM_ROFFSET]))[0] = 0;
+ SAFEALIGN_SET_UINT32(&body[rzero+MNUM_ROFFSET], 0, NULL);
/* 8-X: sequence of strings (name, passwd, mem..) */
if (add_domain) {
@@ -1688,7 +1687,7 @@ static int fill_grent(struct sss_packet *packet,
if (memnum) {
/* set num of members */
- ((uint32_t *)(&body[rzero+MNUM_ROFFSET]))[0] = memnum;
+ SAFEALIGN_SET_UINT32(&body[rzero+MNUM_ROFFSET], memnum, NULL);
}
}
diff --git a/src/sss_client/group.c b/src/sss_client/group.c
index 675b8b71e..e1b36e2a4 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];
+ SAFEALIGN_COPY_UINT32(&c, buf, NULL);
+ pr->result->gr_gid = c;
+ SAFEALIGN_COPY_UINT32(&mem_num, buf+sizeof(uint32_t), NULL);
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 0d70b6843..aa5c76023 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];
+ SAFEALIGN_COPY_UINT32(&c, buf, NULL);
+ pr->result->pw_uid = c;
+ SAFEALIGN_COPY_UINT32(&c, buf+sizeof(uint32_t), NULL);
+ pr->result->pw_gid = c;
sbuf = (char *)&buf[8];
slen = *len - 8;
diff --git a/src/sss_client/sss_cli.h b/src/sss_client/sss_cli.h
index 1953db2f4..2edd158db 100644
--- a/src/sss_client/sss_cli.h
+++ b/src/sss_client/sss_cli.h
@@ -408,6 +408,20 @@ int sss_pam_make_request(enum sss_cli_command cmd,
uint8_t **repbuf, size_t *replen,
int *errnop);
+#ifndef SAFEALIGN_COPY_UINT32
+static inline void
+safealign_memcpy(void *dest, const void *src, size_t n, size_t *counter)
+{
+ memcpy(dest, src, n);
+ if (counter) {
+ *counter += n;
+ }
+}
+
+#define SAFEALIGN_COPY_UINT32(dest, src, pctr) \
+ safealign_memcpy(dest, src, sizeof(uint32_t), pctr)
+#endif
+
#endif /* _SSSCLI_H */
#if 0
str">"disabling mod_ssl in httpd", self.__disable_mod_ssl) self.step("Setting mod_nss port to 443", self.__set_mod_nss_port) self.step("Adding URL rewriting rules", self.__add_include) self.step("configuring httpd", self.__configure_http) self.step("creating a keytab for httpd", self.__create_http_keytab) self.step("Setting up ssl", self.__setup_ssl) if autoconfig: self.step("Setting up browser autoconfig", self.__setup_autoconfig) self.step("configuring SELinux for httpd", self.__selinux_config) self.step("restarting httpd", self.__start) self.step("configuring httpd to start on boot", self.__enable) self.start_creation("Configuring the web interface") def __start(self): self.backup_state("running", self.is_running()) self.restart() def __enable(self): self.backup_state("enabled", self.is_running()) self.chkconfig_on() def __selinux_config(self): selinux=0 try: if (os.path.exists('/usr/sbin/selinuxenabled')): ipautil.run(["/usr/sbin/selinuxenabled"]) selinux=1 except ipautil.CalledProcessError: # selinuxenabled returns 1 if not enabled pass if selinux: try: # returns e.g. "httpd_can_network_connect --> off" (stdout, stderr) = ipautils.run(["/usr/sbin/getsebool", "httpd_can_network_connect"]) self.backup_state("httpd_can_network_connect", stdout.split()[2]) except: pass # Allow apache to connect to the turbogears web gui # This can still fail even if selinux is enabled try: ipautil.run(["/usr/sbin/setsebool", "-P", "httpd_can_network_connect", "true"]) except: self.print_msg(selinux_warning) def __create_http_keytab(self): http_principal = "HTTP/" + self.fqdn + "@" + self.realm installutils.kadmin_addprinc(http_principal) installutils.create_keytab("/etc/httpd/conf/ipa.keytab", http_principal) pent = pwd.getpwnam("apache") os.chown("/etc/httpd/conf/ipa.keytab", pent.pw_uid, pent.pw_gid) def __configure_http(self): http_txt = ipautil.template_file(ipautil.SHARE_DIR + "ipa.conf", self.sub_dict) self.fstore.backup_file("/etc/httpd/conf.d/ipa.conf") http_fd = open("/etc/httpd/conf.d/ipa.conf", "w") http_fd.write(http_txt) http_fd.close() http_txt = ipautil.template_file(ipautil.SHARE_DIR + "ipa-rewrite.conf", self.sub_dict) self.fstore.backup_file("/etc/httpd/conf.d/ipa-rewrite.conf") http_fd = open("/etc/httpd/conf.d/ipa-rewrite.conf", "w") http_fd.write(http_txt) http_fd.close() def __disable_mod_ssl(self): if os.path.exists(SSL_CONF): self.fstore.backup_file(SSL_CONF) os.unlink(SSL_CONF) def __set_mod_nss_port(self): self.fstore.backup_file(NSS_CONF) if installutils.update_file(NSS_CONF, '8443', '443') != 0: print "Updating port in %s failed." % NSS_CONF def __set_mod_nss_nickname(self, nickname): installutils.set_directive(NSS_CONF, 'NSSNickname', nickname) def __add_include(self): """This should run after __set_mod_nss_port so is already backed up""" if installutils.update_file(NSS_CONF, '</VirtualHost>', 'Include conf.d/ipa-rewrite.conf\n</VirtualHost>') != 0: print "Adding Include conf.d/ipa-rewrite to %s failed." % NSS_CONF def __setup_ssl(self): ds_ca = certs.CertDB(dsinstance.config_dirname(dsinstance.realm_to_serverid(self.realm))) ca = certs.CertDB(NSS_DIR) if self.pkcs12_info: ca.create_from_pkcs12(self.pkcs12_info[0], self.pkcs12_info[1], passwd="") server_certs = ca.find_server_certs() if len(server_certs) == 0: raise RuntimeError("Could not find a suitable server cert in import in %s" % pkcs12_info[0]) # We only handle one server cert nickname = server_certs[0][0] self.__set_mod_nss_nickname(nickname) else: ca.create_from_cacert(ds_ca.cacert_fname) ca.create_server_cert("Server-Cert", "cn=%s,ou=Apache Web Server" % self.fqdn, ds_ca) ca.create_signing_cert("Signing-Cert", "cn=%s,ou=Signing Certificate,o=Identity Policy Audit" % self.fqdn, ds_ca) # Fix the database permissions os.chmod(NSS_DIR + "/cert8.db", 0640) os.chmod(NSS_DIR + "/key3.db", 0640) os.chmod(NSS_DIR + "/secmod.db", 0640) pent = pwd.getpwnam("apache") os.chown(NSS_DIR + "/cert8.db", 0, pent.pw_gid ) os.chown(NSS_DIR + "/key3.db", 0, pent.pw_gid ) os.chown(NSS_DIR + "/secmod.db", 0, pent.pw_gid ) def __setup_autoconfig(self): prefs_txt = ipautil.template_file(ipautil.SHARE_DIR + "preferences.html.template", self.sub_dict) prefs_fd = open("/usr/share/ipa/html/preferences.html", "w") prefs_fd.write(prefs_txt) prefs_fd.close() # The signing cert is generated in __setup_ssl ds_ca = certs.CertDB(dsinstance.config_dirname(dsinstance.realm_to_serverid(self.realm))) ca = certs.CertDB(NSS_DIR) # Publish the CA certificate shutil.copy(ds_ca.cacert_fname, "/usr/share/ipa/html/ca.crt") os.chmod("/usr/share/ipa/html/ca.crt", 0444) tmpdir = tempfile.mkdtemp(prefix = "tmp-") shutil.copy("/usr/share/ipa/html/preferences.html", tmpdir) ca.run_signtool(["-k", "Signing-Cert", "-Z", "/usr/share/ipa/html/configure.jar", "-e", ".html", tmpdir]) shutil.rmtree(tmpdir) def uninstall(self): running = self.restore_state("running") enabled = self.restore_state("enabled") if not running is None: self.stop() if not enabled is None and not enabled: self.chkconfig_off() for f in ["/etc/httpd/conf.d/ipa.conf", SSL_CONF, NSS_CONF]: try: self.fstore.restore_file(f) except ValueError, error: logging.debug(error) pass sebool_state = self.restore_state("httpd_can_network_connect") if not sebool_state is None: try: ipautil.run(["/usr/sbin/setsebool", "-P", "httpd_can_network_connect", sebool_state]) except: self.print_msg(selinux_warning) if not running is None and running: self.start()