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/krb5/krb5_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/krb5/krb5_child.c')
-rw-r--r-- | server/providers/krb5/krb5_child.c | 83 |
1 files changed, 43 insertions, 40 deletions
diff --git a/server/providers/krb5/krb5_child.c b/server/providers/krb5/krb5_child.c index 6eb420bc..6b4c7cc0 100644 --- a/server/providers/krb5/krb5_child.c +++ b/server/providers/krb5/krb5_child.c @@ -339,8 +339,9 @@ static struct response *prepare_response_message(struct krb5_req *kr, static errno_t sendresponse(int fd, krb5_error_code kerr, int pam_status, struct krb5_req *kr) { - int ret; struct response *resp; + size_t written; + int ret; resp = prepare_response_message(kr, kerr, pam_status); if (resp == NULL) { @@ -348,10 +349,18 @@ static errno_t sendresponse(int fd, krb5_error_code kerr, int pam_status, return ENOMEM; } - ret = write(fd, resp->buf, resp->size); - if (ret == -1) { - DEBUG(1, ("write failed [%d][%s].\n", errno, strerror(errno))); - return errno; + written = 0; + while (written < resp->size) { + ret = write(fd, 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; } return EOK; @@ -680,79 +689,71 @@ static errno_t unpack_buffer(uint8_t *buf, size_t size, struct pam_data *pd, char **ccname, char **keytab, uint32_t *validate) { size_t p = 0; - uint32_t *len; + uint32_t len; if ((p + sizeof(uint32_t)) > size) return EINVAL; - len = ((uint32_t *)(buf+p)); - pd->cmd = *len; + pd->cmd = *((uint32_t *)(buf + p)); p += sizeof(uint32_t); if ((p + sizeof(uint32_t)) > size) return EINVAL; - len = ((uint32_t *)(buf+p)); - pd->pw_uid = *len; + pd->pw_uid = *((uint32_t *)(buf + p)); p += sizeof(uint32_t); if ((p + sizeof(uint32_t)) > size) return EINVAL; - len = ((uint32_t *)(buf+p)); - pd->gr_gid = *len; + pd->gr_gid = *((uint32_t *)(buf + p)); p += sizeof(uint32_t); if ((p + sizeof(uint32_t)) > size) return EINVAL; - len = ((uint32_t *)(buf+p)); - *validate = *len; + *validate = *((uint32_t *)(buf + p)); p += sizeof(uint32_t); if ((p + sizeof(uint32_t)) > size) return EINVAL; - len = ((uint32_t *)(buf+p)); + len = *((uint32_t *)(buf + p)); p += sizeof(uint32_t); - if ((p + *len ) > size) return EINVAL; - pd->upn = (char *) copy_buffer_and_add_zero(pd, buf+p, - sizeof(char) * (*len)); + if ((p + len ) > size) return EINVAL; + pd->upn = talloc_strndup(pd, (char *)(buf + p), len); if (pd->upn == NULL) return ENOMEM; - p += *len; + p += len; if ((p + sizeof(uint32_t)) > size) return EINVAL; - len = ((uint32_t *)(buf+p)); + len = *((uint32_t *)(buf + p)); p += sizeof(uint32_t); - if ((p + *len ) > size) return EINVAL; - *ccname = (char *) copy_buffer_and_add_zero(pd, buf+p, - sizeof(char) * (*len)); + if ((p + len ) > size) return EINVAL; + *ccname = talloc_strndup(pd, (char *)(buf + p), len); if (*ccname == NULL) return ENOMEM; - p += *len; + p += len; if ((p + sizeof(uint32_t)) > size) return EINVAL; - len = ((uint32_t *)(buf+p)); + len = *((uint32_t *)(buf + p)); p += sizeof(uint32_t); - if ((p + *len ) > size) return EINVAL; - *keytab = (char *) copy_buffer_and_add_zero(pd, buf+p, - sizeof(char) * (*len)); + if ((p + len ) > size) return EINVAL; + *keytab = talloc_strndup(pd, (char *)(buf + p), len); if (*keytab == NULL) return ENOMEM; - p += *len; + p += len; if ((p + sizeof(uint32_t)) > size) return EINVAL; - len = ((uint32_t *)(buf+p)); + len = *((uint32_t *)(buf + p)); p += sizeof(uint32_t); - if ((p + *len) > size) return EINVAL; - pd->authtok = copy_buffer_and_add_zero(pd, buf+p, sizeof(char) * (*len)); + if ((p + len) > size) return EINVAL; + pd->authtok = (uint8_t *)talloc_strndup(pd, (char *)(buf + p), len); if (pd->authtok == NULL) return ENOMEM; - pd->authtok_size = *len + 1; - p += *len; + pd->authtok_size = len + 1; + p += len; if (pd->cmd == SSS_PAM_CHAUTHTOK) { if ((p + sizeof(uint32_t)) > size) return EINVAL; - len = ((uint32_t *)(buf+p)); + len = *((uint32_t *)(buf + p)); p += sizeof(uint32_t); - if ((p + *len) > size) return EINVAL; - pd->newauthtok = copy_buffer_and_add_zero(pd, buf+p, - sizeof(char) * (*len)); + if ((p + len) > size) return EINVAL; + pd->newauthtok = (uint8_t *)talloc_strndup(pd, (char *)(buf + p), len); if (pd->newauthtok == NULL) return ENOMEM; - pd->newauthtok_size = *len + 1; - p += *len; + pd->newauthtok_size = len + 1; + p += len; } else { pd->newauthtok = NULL; pd->newauthtok_size = 0; @@ -938,6 +939,8 @@ int main(int argc, const char *argv[]) poptFreeContext(pc); + DEBUG(7, ("krb5_child started.\n")); + pd = talloc(NULL, struct pam_data); if (pd == NULL) { DEBUG(1, ("malloc failed.\n")); |