summaryrefslogtreecommitdiff
path: root/server/providers/ldap/ldap_child.c
diff options
context:
space:
mode:
authorSimo Sorce <ssorce@redhat.com>2009-12-18 10:23:41 -0500
committerStephen Gallagher <sgallagh@redhat.com>2009-12-18 15:41:30 -0500
commitbb78a286dbc90d248bd7a9d29344de87051920f2 (patch)
tree79dc659b368e88e7fe247fe535fc48b83862d50e /server/providers/ldap/ldap_child.c
parent6b94e84a0455ebb68506e70cf8ccc2a4656a2c91 (diff)
downloadsssd-bb78a286dbc90d248bd7a9d29344de87051920f2.tar.gz
sssd-bb78a286dbc90d248bd7a9d29344de87051920f2.tar.bz2
sssd-bb78a286dbc90d248bd7a9d29344de87051920f2.zip
Fix ldap child memory hierarchy and other issues
The timeout handler was not a child of the request so it could fire even though the request was already freed. The code wouldn't use async writes to the children so it could incur in a short write with no way to detect or recover from it. Also fixed style of some helper functions to pass explicit paramters instead of a general structure. Add common code to do async writes to pipes. Fixed async write issue for the krb5_child as well. Fix also sdap_kinit_done(), a return statement was missing and we were mixing SDAP_AUTH and errno return codes in state->result Remove usless helper function that just replicates talloc_strndup()
Diffstat (limited to 'server/providers/ldap/ldap_child.c')
-rw-r--r--server/providers/ldap/ldap_child.c64
1 files changed, 36 insertions, 28 deletions
diff --git a/server/providers/ldap/ldap_child.c b/server/providers/ldap/ldap_child.c
index 9c11bf40..4a577b87 100644
--- a/server/providers/ldap/ldap_child.c
+++ b/server/providers/ldap/ldap_child.c
@@ -42,10 +42,11 @@ struct input_buffer {
const char *keytab_name;
};
-static errno_t unpack_buffer(uint8_t *buf, size_t size, struct input_buffer *ibuf)
+static errno_t unpack_buffer(uint8_t *buf, size_t size,
+ struct input_buffer *ibuf)
{
size_t p = 0;
- uint32_t *len;
+ uint32_t len;
/* realm_str size and length */
DEBUG(7, ("total buffer size: %d\n", size));
@@ -53,47 +54,44 @@ static errno_t unpack_buffer(uint8_t *buf, size_t size, struct input_buffer *ibu
DEBUG(1, ("Error: buffer too big!\n"));
return EINVAL;
}
- len = ((uint32_t *)(buf+p));
+ len = ((uint32_t *)(buf + p))[0];
p += sizeof(uint32_t);
- DEBUG(7, ("realm_str size: %d\n", *len));
- if (*len) {
- if ((p + *len ) > size) return EINVAL;
- ibuf->realm_str = (char *) copy_buffer_and_add_zero(ibuf, buf+p,
- sizeof(char) * (*len));
+ DEBUG(7, ("realm_str size: %d\n", len));
+ if (len) {
+ if ((p + len ) > size) return EINVAL;
+ ibuf->realm_str = talloc_strndup(ibuf, (char *)(buf + p), len);
DEBUG(7, ("got realm_str: %s\n", ibuf->realm_str));
if (ibuf->realm_str == NULL) return ENOMEM;
- p += *len;
+ p += len;
}
/* princ_str size and length */
if ((p + sizeof(uint32_t)) > size) return EINVAL;
- len = ((uint32_t *)(buf+p));
+ len = ((uint32_t *)(buf + p))[0];
p += sizeof(uint32_t);
- DEBUG(7, ("princ_str size: %d\n", *len));
- if (*len) {
- if ((p + *len ) > size) return EINVAL;
- ibuf->princ_str = (char *) copy_buffer_and_add_zero(ibuf, buf+p,
- sizeof(char) * (*len));
+ DEBUG(7, ("princ_str size: %d\n", len));
+ if (len) {
+ if ((p + len ) > size) return EINVAL;
+ ibuf->princ_str = talloc_strndup(ibuf, (char *)(buf + p), len);
DEBUG(7, ("got princ_str: %s\n", ibuf->princ_str));
if (ibuf->princ_str == NULL) return ENOMEM;
- p += *len;
+ p += len;
}
/* keytab_name size and length */
if ((p + sizeof(uint32_t)) > size) return EINVAL;
- len = ((uint32_t *)(buf+p));
+ len = ((uint32_t *)(buf + p))[0];
p += sizeof(uint32_t);
- DEBUG(7, ("keytab_name size: %d\n", *len));
- if (*len) {
- if ((p + *len ) > size) return EINVAL;
- ibuf->keytab_name = (char *) copy_buffer_and_add_zero(ibuf, buf+p,
- sizeof(char) * (*len));
+ DEBUG(7, ("keytab_name size: %d\n", len));
+ if (len) {
+ if ((p + len ) > size) return EINVAL;
+ ibuf->keytab_name = talloc_strndup(ibuf, (char *)(buf + p), len);
DEBUG(7, ("got keytab_name: %s\n", ibuf->keytab_name));
if (ibuf->keytab_name == NULL) return ENOMEM;
- p += *len;
+ p += len;
}
return EOK;
@@ -321,6 +319,7 @@ int main(int argc, const char *argv[])
const char *ccname = NULL;
struct input_buffer *ibuf = NULL;
struct response *resp = NULL;
+ size_t written;
struct poptOption long_options[] = {
POPT_AUTOHELP
@@ -346,6 +345,8 @@ int main(int argc, const char *argv[])
poptFreeContext(pc);
+ DEBUG(7, ("ldap_child started.\n"));
+
main_ctx = talloc_new(NULL);
if (main_ctx == NULL) {
DEBUG(1, ("talloc_new failed.\n"));
@@ -414,11 +415,18 @@ int main(int argc, const char *argv[])
return ENOMEM;
}
- ret = write(STDOUT_FILENO, resp->buf, resp->size);
- if (ret == -1) {
- ret = errno;
- DEBUG(1, ("write failed [%d][%s].\n", ret, strerror(ret)));
- return errno;
+ written = 0;
+ while (written < resp->size) {
+ ret = write(STDOUT_FILENO, resp->buf + written, resp->size - written);
+ if (ret == -1) {
+ if (errno == EAGAIN || errno == EINTR) {
+ continue;
+ }
+ ret = errno;
+ DEBUG(1, ("write failed [%d][%s].\n", ret, strerror(ret)));
+ return ret;
+ }
+ written += ret;
}
close(STDOUT_FILENO);