コード例 #1
0
ファイル: kt_memory.c プロジェクト: FarazShaikh/likewise-open
krb5_error_code KRB5_CALLCONV
krb5_mkt_get_name(krb5_context context, krb5_keytab id, char *name, unsigned int len)
{
    int result;

    memset(name, 0, len);
    result = snprintf(name, len, "%s:%s", id->ops->prefix, KTNAME(id));
    if (SNPRINTF_OVERFLOW(result, len))
	return(KRB5_KT_NAME_TOOLONG);
    return(0);
}
コード例 #2
0
ファイル: asn1_encode.c プロジェクト: Brainiarc7/pbis
asn1_error_code
asn1_encode_generaltime(asn1buf *buf, time_t val, unsigned int *retlen)
{
    struct tm *gtime, gtimebuf;
    char s[16], *sp;
    time_t gmt_time = val;

    /*
     * Time encoding: YYYYMMDDhhmmssZ
     */
    if (gmt_time == 0) {
        sp = "19700101000000Z";
    } else {
        int len;

        /*
         * Sanity check this just to be paranoid, as gmtime can return NULL,
         * and some bogus implementations might overrun on the sprintf.
         */
#ifdef HAVE_GMTIME_R
# ifdef GMTIME_R_RETURNS_INT
        if (gmtime_r(&gmt_time, &gtimebuf) != 0)
            return ASN1_BAD_GMTIME;
# else
        if (gmtime_r(&gmt_time, &gtimebuf) == NULL)
            return ASN1_BAD_GMTIME;
# endif
#else
        gtime = gmtime(&gmt_time);
        if (gtime == NULL)
            return ASN1_BAD_GMTIME;
        memcpy(&gtimebuf, gtime, sizeof(gtimebuf));
#endif
        gtime = &gtimebuf;

        if (gtime->tm_year > 8099 || gtime->tm_mon > 11 ||
            gtime->tm_mday > 31 || gtime->tm_hour > 23 ||
            gtime->tm_min > 59 || gtime->tm_sec > 59)
            return ASN1_BAD_GMTIME;
        len = snprintf(s, sizeof(s), "%04d%02d%02d%02d%02d%02dZ",
                       1900+gtime->tm_year, gtime->tm_mon+1,
                       gtime->tm_mday, gtime->tm_hour,
                       gtime->tm_min, gtime->tm_sec);
        if (SNPRINTF_OVERFLOW(len, sizeof(s)))
            /* Shouldn't be possible given above tests.  */
            return ASN1_BAD_GMTIME;
        sp = s;
    }

    return encode_bytestring_with_tag(buf, 15, sp, ASN1_GENERALTIME,
                                      retlen);
}
コード例 #3
0
/*
 * Resolve the entry in servers with index ind, adding connections to the list
 * *conns.  Connections are added for each of socktype1 and (if not zero)
 * socktype2.  message and udpbufp are used to initialize the connections; see
 * add_connection above.  If no addresses are available for an entry but no
 * internal name resolution failure occurs, return 0 without adding any new
 * connections.
 */
static krb5_error_code
resolve_server(krb5_context context, const struct serverlist *servers,
               size_t ind, int socktype1, int socktype2,
               const krb5_data *message, char **udpbufp,
               struct conn_state **conns)
{
    krb5_error_code retval;
    struct server_entry *entry = &servers->servers[ind];
    struct addrinfo *addrs, *a, hint, ai;
    int err, result;
    char portbuf[64];

    /* Skip any stray entries of socktypes we don't want. */
    if (entry->socktype != 0 && entry->socktype != socktype1 &&
        entry->socktype != socktype2)
        return 0;

    if (entry->hostname == NULL) {
        ai.ai_socktype = entry->socktype;
        ai.ai_family = entry->family;
        ai.ai_addrlen = entry->addrlen;
        ai.ai_addr = (struct sockaddr *)&entry->addr;
        return add_connection(conns, &ai, ind, message, udpbufp);
    }

    memset(&hint, 0, sizeof(hint));
    hint.ai_family = entry->family;
    hint.ai_socktype = (entry->socktype != 0) ? entry->socktype : socktype1;
#ifdef AI_NUMERICSERV
    hint.ai_flags = AI_NUMERICSERV;
#endif
    result = snprintf(portbuf, sizeof(portbuf), "%d", ntohs(entry->port));
    if (SNPRINTF_OVERFLOW(result, sizeof(portbuf)))
        return EINVAL;
    TRACE_SENDTO_KDC_RESOLVING(context, entry->hostname);
    err = getaddrinfo(entry->hostname, portbuf, &hint, &addrs);
    if (err)
        return translate_ai_error(err);
    /* Add each address with the preferred socktype. */
    retval = 0;
    for (a = addrs; a != 0 && retval == 0; a = a->ai_next)
        retval = add_connection(conns, a, ind, message, udpbufp);
    if (retval == 0 && entry->socktype == 0 && socktype2 != 0) {
        /* Add each address again with the non-preferred socktype. */
        for (a = addrs; a != 0 && retval == 0; a = a->ai_next) {
            a->ai_socktype = socktype2;
            retval = add_connection(conns, a, ind, message, udpbufp);
        }
    }
    freeaddrinfo(addrs);
    return retval;
}
コード例 #4
0
ファイル: kt_srvtab.c プロジェクト: FarazShaikh/LikewiseSMB2
krb5_error_code KRB5_CALLCONV
krb5_ktsrvtab_get_name(krb5_context context, krb5_keytab id, char *name, unsigned int len)
  /* 
   * This routine returns the name of the name of the file associated with
   * this srvtab-based keytab.  The name is prefixed with PREFIX:, so that
   * trt will happen if the name is passed back to resolve.
   */
{
    int result;

    memset(name, 0, len);
    result = snprintf(name, len, "%s:%s", id->ops->prefix, KTFILENAME(id));
    if (SNPRINTF_OVERFLOW(result, len))
	return(KRB5_KT_NAME_TOOLONG);
    return(0);
}
コード例 #5
0
ファイル: sendto_kdc.c プロジェクト: Akasurde/krb5
/*
 * Resolve the entry in servers with index ind, adding connections to the list
 * *conns.  Connections are added for each of socktype1 and (if not zero)
 * socktype2.  message and udpbufp are used to initialize the connections; see
 * add_connection above.  If no addresses are available for an entry but no
 * internal name resolution failure occurs, return 0 without adding any new
 * connections.
 */
static krb5_error_code
resolve_server(krb5_context context, const krb5_data *realm,
               const struct serverlist *servers, size_t ind,
               k5_transport_strategy strategy, const krb5_data *message,
               char **udpbufp, struct conn_state **conns)
{
    krb5_error_code retval;
    struct server_entry *entry = &servers->servers[ind];
    k5_transport transport;
    struct addrinfo *addrs, *a, hint, ai;
    krb5_boolean defer;
    int err, result;
    char portbuf[64];

    /* Skip UDP entries if we don't want UDP. */
    if (strategy == NO_UDP && entry->transport == UDP)
        return 0;

    transport = (strategy == UDP_FIRST) ? UDP : TCP;
    if (entry->hostname == NULL) {
        /* Added by a module, so transport is either TCP or UDP. */
        ai.ai_socktype = socktype_for_transport(entry->transport);
        ai.ai_family = entry->family;
        ai.ai_addrlen = entry->addrlen;
        ai.ai_addr = (struct sockaddr *)&entry->addr;
        defer = (entry->transport != transport);
        return add_connection(conns, entry->transport, defer, &ai, ind, realm,
                              NULL, entry->uri_path, udpbufp);
    }

    /* If the entry has a specified transport, use it. */
    if (entry->transport != TCP_OR_UDP)
        transport = entry->transport;

    memset(&hint, 0, sizeof(hint));
    hint.ai_family = entry->family;
    hint.ai_socktype = socktype_for_transport(transport);
    hint.ai_flags = AI_ADDRCONFIG;
#ifdef AI_NUMERICSERV
    hint.ai_flags |= AI_NUMERICSERV;
#endif
    result = snprintf(portbuf, sizeof(portbuf), "%d", ntohs(entry->port));
    if (SNPRINTF_OVERFLOW(result, sizeof(portbuf)))
        return EINVAL;
    TRACE_SENDTO_KDC_RESOLVING(context, entry->hostname);
    err = getaddrinfo(entry->hostname, portbuf, &hint, &addrs);
    if (err)
        return translate_ai_error(err);

    /* Add each address with the specified or preferred transport. */
    retval = 0;
    for (a = addrs; a != 0 && retval == 0; a = a->ai_next) {
        retval = add_connection(conns, transport, FALSE, a, ind, realm,
                                entry->hostname, entry->uri_path, udpbufp);
    }

    /* For TCP_OR_UDP entries, add each address again with the non-preferred
     * transport, unless we are avoiding UDP.  Flag these as deferred. */
    if (retval == 0 && entry->transport == TCP_OR_UDP && strategy != NO_UDP) {
        transport = (strategy == UDP_FIRST) ? TCP : UDP;
        for (a = addrs; a != 0 && retval == 0; a = a->ai_next) {
            a->ai_socktype = socktype_for_transport(transport);
            retval = add_connection(conns, transport, TRUE, a, ind, realm,
                                    entry->hostname, entry->uri_path, udpbufp);
        }
    }
    freeaddrinfo(addrs);
    return retval;
}
コード例 #6
0
ファイル: k5buf.c プロジェクト: WeiY/krb5
void
k5_buf_add_fmt(struct k5buf *buf, const char *fmt, ...)
{
    va_list ap;
    int r;
    size_t remaining;
    char *tmp;

    if (buf->buftype == BUFTYPE_ERROR)
        return;
    remaining = buf->space - buf->len;

    if (buf->buftype == BUFTYPE_FIXED) {
        /* Format the data directly into the fixed buffer. */
        va_start(ap, fmt);
        r = vsnprintf(buf->data + buf->len, remaining, fmt, ap);
        va_end(ap);
        if (SNPRINTF_OVERFLOW(r, remaining))
            buf->buftype = BUFTYPE_ERROR;
        else
            buf->len += (unsigned int) r;
        return;
    }

    /* Optimistically format the data directly into the dynamic buffer. */
    assert(buf->buftype == BUFTYPE_DYNAMIC);
    va_start(ap, fmt);
    r = vsnprintf(buf->data + buf->len, remaining, fmt, ap);
    va_end(ap);
    if (!SNPRINTF_OVERFLOW(r, remaining)) {
        buf->len += (unsigned int) r;
        return;
    }

    if (r >= 0) {
        /* snprintf correctly told us how much space is required. */
        if (!ensure_space(buf, r))
            return;
        remaining = buf->space - buf->len;
        va_start(ap, fmt);
        r = vsnprintf(buf->data + buf->len, remaining, fmt, ap);
        va_end(ap);
        if (SNPRINTF_OVERFLOW(r, remaining))  /* Shouldn't ever happen. */
            buf->buftype = BUFTYPE_ERROR;
        else
            buf->len += (unsigned int) r;
        return;
    }

    /* It's a pre-C99 snprintf implementation, or something else went wrong.
     * Fall back to asprintf. */
    va_start(ap, fmt);
    r = vasprintf(&tmp, fmt, ap);
    va_end(ap);
    if (r < 0) {
        buf->buftype = BUFTYPE_ERROR;
        return;
    }
    if (ensure_space(buf, r)) {
        /* Copy the temporary string into buf, including terminator. */
        memcpy(buf->data + buf->len, tmp, r + 1);
        buf->len += r;
    }
    free(tmp);
}
コード例 #7
0
ファイル: k5buf.c プロジェクト: PADL/krb5
void
k5_buf_add_vfmt(struct k5buf *buf, const char *fmt, va_list ap)
{
    va_list apcopy;
    int r;
    size_t remaining;
    char *tmp;

    if (buf->buftype == K5BUF_ERROR)
        return;
    remaining = buf->space - buf->len;

    if (buf->buftype == K5BUF_FIXED) {
        /* Format the data directly into the fixed buffer. */
        r = vsnprintf(endptr(buf), remaining, fmt, ap);
        if (SNPRINTF_OVERFLOW(r, remaining))
            set_error(buf);
        else
            buf->len += (unsigned int) r;
        return;
    }

    /* Optimistically format the data directly into the dynamic buffer. */
    assert(buf->buftype == K5BUF_DYNAMIC || buf->buftype == K5BUF_DYNAMIC_ZAP);
    va_copy(apcopy, ap);
    r = vsnprintf(endptr(buf), remaining, fmt, apcopy);
    va_end(apcopy);
    if (!SNPRINTF_OVERFLOW(r, remaining)) {
        buf->len += (unsigned int) r;
        return;
    }

    if (r >= 0) {
        /* snprintf correctly told us how much space is required. */
        if (!ensure_space(buf, r))
            return;
        remaining = buf->space - buf->len;
        r = vsnprintf(endptr(buf), remaining, fmt, ap);
        if (SNPRINTF_OVERFLOW(r, remaining))  /* Shouldn't ever happen. */
            k5_buf_free(buf);
        else
            buf->len += (unsigned int) r;
        return;
    }

    /* It's a pre-C99 snprintf implementation, or something else went wrong.
     * Fall back to asprintf. */
    r = vasprintf(&tmp, fmt, ap);
    if (r < 0) {
        k5_buf_free(buf);
        return;
    }
    if (ensure_space(buf, r)) {
        /* Copy the temporary string into buf, including terminator. */
        memcpy(endptr(buf), tmp, r + 1);
        buf->len += r;
    }
    if (buf->buftype == K5BUF_DYNAMIC_ZAP)
        zap(tmp, strlen(tmp));
    free(tmp);
}