diff options
author | Simo Sorce <ssorce@redhat.com> | 2009-12-18 10:23:41 -0500 |
---|---|---|
committer | Stephen Gallagher <sgallagh@redhat.com> | 2009-12-18 15:41:30 -0500 |
commit | bb78a286dbc90d248bd7a9d29344de87051920f2 (patch) | |
tree | 79dc659b368e88e7fe247fe535fc48b83862d50e /server/providers/ldap/ldap_child.c | |
parent | 6b94e84a0455ebb68506e70cf8ccc2a4656a2c91 (diff) | |
download | sssd-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.c | 64 |
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); |