Exemple #1
0
/*
 * Given the list of hostnames of KDCs found in DNS SRV recs, lets go
 * thru NSS (name svc switch) to get the net addrs.
 */
static krb5_error_code
dns_hostnames2netaddrs(
	struct srv_dns_entry *head,
	enum locate_service_type svc,
	int socktype,
	int family,
	struct addrlist *addrlist)
{
    struct srv_dns_entry *entry = NULL, *next;
    krb5_error_code code;

    Tprintf ("walking answer list:\n");
    for (entry = head; entry != NULL; entry = entry->next) {
	code = 0;
	if (socktype)
	    code = add_host_to_list (addrlist, entry->host,
				    htons (entry->port), 0,
				    socktype, family);
	else {
	    (void) add_host_to_list (addrlist, entry->host,
				    htons (entry->port), 0,
				    SOCK_DGRAM, family);
		
	    code = add_host_to_list (addrlist, entry->host,
				    htons (entry->port), 0,
				    SOCK_STREAM, family);
	}
        if (code) {
	    Tprintf("  fail add_host code=%d %s\n", code, entry->host);
        }
    }
    Tprintf ("[end]\n");

    return code;
}
Exemple #2
0
static krb5_error_code
locate_srv_dns_1(const krb5_data *realm, const char *service,
                 const char *protocol, struct serverlist *serverlist)
{
    struct srv_dns_entry *head = NULL, *entry = NULL;
    krb5_error_code code = 0;
    int socktype;

    code = krb5int_make_srv_query_realm(realm, service, protocol, &head);
    if (code)
        return 0;

    if (head == NULL)
        return 0;

    /* Check for the "." case indicating no support.  */
    if (head->next == NULL && head->host[0] == '\0') {
        code = KRB5_ERR_NO_SERVICE;
        goto cleanup;
    }

    for (entry = head; entry != NULL; entry = entry->next) {
        socktype = (strcmp(protocol, "_tcp") == 0) ? SOCK_STREAM : SOCK_DGRAM;
        code = add_host_to_list(serverlist, entry->host, htons(entry->port),
                                socktype, AF_UNSPEC);
        if (code)
            goto cleanup;
    }

cleanup:
    krb5int_free_srv_dns_data(head);
    return code;
}
Exemple #3
0
static krb5_error_code
locate_srv_dns_1(krb5_context context, const krb5_data *realm,
                 const char *service, const char *protocol,
                 struct serverlist *serverlist)
{
    struct srv_dns_entry *head = NULL, *entry = NULL;
    krb5_error_code code = 0;
    k5_transport transport;

    code = krb5int_make_srv_query_realm(context, realm, service, protocol,
                                        &head);
    if (code)
        return 0;

    if (head == NULL)
        return 0;

    /* Check for the "." case indicating no support.  */
    if (head->next == NULL && head->host[0] == '\0') {
        code = KRB5_ERR_NO_SERVICE;
        goto cleanup;
    }

    for (entry = head; entry != NULL; entry = entry->next) {
        transport = (strcmp(protocol, "_tcp") == 0) ? TCP : UDP;
        code = add_host_to_list(serverlist, entry->host, entry->port,
                                transport, AF_UNSPEC, NULL, -1);
        if (code)
            goto cleanup;
    }

cleanup:
    krb5int_free_srv_dns_data(head);
    return code;
}
Exemple #4
0
/*
 * Collect a list of servers from DNS URI records, for the requested service
 * and transport type.  Problematic entries are skipped.
 */
static krb5_error_code
locate_uri(krb5_context context, const krb5_data *realm,
           const char *req_service, struct serverlist *serverlist,
           k5_transport req_transport, int default_port,
           krb5_boolean master_only)
{
    krb5_error_code ret;
    k5_transport transport, host_trans;
    struct srv_dns_entry *answers, *entry;
    char *host;
    const char *host_field, *path;
    int port, def_port, master;

    ret = k5_make_uri_query(context, realm, req_service, &answers);
    if (ret || answers == NULL)
        return ret;

    for (entry = answers; entry != NULL; entry = entry->next) {
        def_port = default_port;
        path = NULL;

        parse_uri_fields(entry->host, &transport, &host_field, &master);
        if (host_field == NULL)
            continue;

        /* TCP_OR_UDP allows entries of any transport type; otherwise
         * we're asking for a match. */
        if (req_transport != TCP_OR_UDP && req_transport != transport)
            continue;

        /* Process a MS-KKDCP target. */
        if (transport == HTTPS) {
            host_trans = 0;
            def_port = 443;
            parse_uri_if_https(host_field, &host_trans, &host_field, &path);
            if (host_trans != HTTPS)
                continue;
        }

        ret = k5_parse_host_string(host_field, def_port, &host, &port);
        if (ret == ENOMEM)
            break;

        if (ret || host == NULL) {
            ret = 0;
            continue;
        }

        ret = add_host_to_list(serverlist, host, port, transport, AF_UNSPEC,
                               path, master);
        free(host);
        if (ret)
            break;
    }

    krb5int_free_srv_dns_data(answers);
    return ret;
}
Exemple #5
0
void 
add_hosts_in_subnet_to_list(char *ipsubnet)
{
  char *ipaddr = cl_malloc(strlen(ipsubnet) + 4);        /* 3 digits, NUL */
  int i;

  for (i = 1; i <= 255; i++) {
    sprintf(ipaddr, "%s%d", ipsubnet, i);
    add_host_to_list(ipaddr);
  }
  cl_free(ipaddr);
}
Exemple #6
0
/*
 * Take the profile KDC list and return a list of net addrs.
 */
static krb5_error_code
prof_hostnames2netaddrs(
	char **hostlist,
	enum locate_service_type svc,
	int socktype,
	int family,
	struct addrlist *addrlist) /* output */
{
	int udpport  = 0 , sec_udpport = 0;
	int code, i;
	struct servent *serv;

	int count = 0;
	while (hostlist && hostlist[count])
		count++;
	if (count == 0) {
		return 0;
	}
    
    switch (svc) {
    case locate_service_kdc:
    case locate_service_master_kdc:
	/* We used to use /etc/services for these, but enough systems
	   have old, crufty, wrong settings that this is probably
	   better.  */
	udpport = htons(KRB5_DEFAULT_PORT);
	sec_udpport = htons(KRB5_DEFAULT_SEC_PORT);
	break;
    case locate_service_kadmin:
	udpport = htons(DEFAULT_KADM5_PORT);
	break;
    case locate_service_krb524:
	serv = getservbyname(KRB524_SERVICE, "udp");
	udpport = serv ? serv->s_port : htons (KRB524_PORT);
	break;
    case locate_service_kpasswd:
	udpport = htons(DEFAULT_KPASSWD_PORT);
	break;
    default:
	return EINVAL;
    }

    for (i=0; hostlist[i]; i++) {
	int p1, p2;
	char *cp, *port, *host;

	host = hostlist[i];
	/*
	 * Strip off excess whitespace
	 */
	cp = strchr(host, ' ');
	if (cp)
	    *cp = 0;
	cp = strchr(host, '\t');
	if (cp)
	    *cp = 0;
	port = strchr(host, ':');
	if (port) {
	    *port = 0;
	    port++;
	}

	if (port) {
	    unsigned long l;
#ifdef HAVE_STROUL
	    char *endptr;
	    l = strtoul (port, &endptr, 10);
	    if (endptr == NULL || *endptr != 0)
		return EINVAL;
#else
	    l = atoi (port);
#endif
	    /* L is unsigned, don't need to check <0.  */
	    if (l == 0 || l > 65535)
		return EINVAL;
	    p1 = htons (l);
	    p2 = 0;
	} else {
	    p1 = udpport;
	    p2 = sec_udpport;
	}


	if (socktype != 0) {
	    code = add_host_to_list (addrlist, hostlist[i], p1, p2,
				     socktype, family);
	} else {
	    code = add_host_to_list (addrlist, hostlist[i], p1, p2,
				     SOCK_DGRAM, family);
	    if (code == 0)
		code = add_host_to_list (addrlist, hostlist[i], p1, p2,
					 SOCK_STREAM, family);
	}
    }

    return code;
}
Exemple #7
0
/**
 * Main function for the cqpserver app.
 */
int
main(int argc, char *argv[])
{
  int cmd;

  which_app = cqpserver;

  /* TODO: shouldn't these come AFTER initialize_cqp(), as that function may overwrite these values with defaults?
   * or maybe I've missed some subtlety here....*/
  silent = 1; 
  paging = autoshow = auto_save = 0;

  if (!initialize_cqp(argc, argv)) {
   Rprintf( "CQPserver: ERROR Couldn't initialise CQP engine.\n");
    rcqp_receive_error(1);
  }
  cqiserver_welcome();

  if (localhost) {
    add_host_to_list("127.0.0.1"); /* in -L mode, connections from localhost are automatically accepted  */
  }

  if (0 < accept_connection(server_port)) {
    if (server_log)
     Rprintf("CQPserver: Connected. Waiting for CONNECT request.\n");
  }
  else {
   Rprintf( "CQPserver: ERROR Connection failed.\n");
    rcqp_receive_error(1);
  }

  /* establish CQi connection: wait for CONNECT request */
  cmd = cqi_read_command();
  if (cmd != CQI_CTRL_CONNECT) {
    if (server_log)
     Rprintf("CQPserver: Connection refused.\n");
    cqiserver_wrong_command_error(cmd);
  }
  user = cqi_read_string();
  passwd = cqi_read_string();
  if (server_log)
   Rprintf("CQPserver: CONNECT  user = '******'  passwd = '%s'  pid = %d\n", user, passwd, (int)getpid());

  /* check password here (always required !!) */
  if (!authenticate_user(user, passwd)) {
   Rprintf("CQPserver: Wrong username or password. Connection refused.\n"); /* TODO shouldn't this be to stderr as it is not conditional on server_log? */
    cqi_command(CQI_ERROR_CONNECT_REFUSED);
  }
  else {
    cqi_command(CQI_STATUS_CONNECT_OK);

    /* re-randomize for query lock key generation */
    cl_randomize();

    /* check which corpora the user is granted access to */
    {
      CorpusList *cl = FirstCorpusFromList();
      while (cl != NULL) {
        if (!check_grant(user, cl->name))
          dropcorpus(cl);
        cl = NextCorpusFromList(cl);
      }
    }

    /* start command interpreter loop */
    interpreter();

    if (server_log)
     Rprintf("CQPserver: User '%s' has logged off.\n", user);
  }

  /* connection terminated; clean up and exit */
 Rprintf("CQPserver: Exit. (pid = %d)\n", (int)getpid());

  /* TODO should we check cqp_error_status as in the main cqp app? */
  return 0;
}
Exemple #8
0
static krb5_error_code
locate_srv_conf_1(krb5_context context, const krb5_data *realm,
                  const char * name, struct serverlist *serverlist,
                  int socktype, int udpport, int sec_udpport)
{
    const char  *realm_srv_names[4];
    char **hostlist, *host, *port, *cp;
    krb5_error_code code;
    int i;

    Tprintf ("looking in krb5.conf for realm %s entry %s; ports %d,%d\n",
             realm->data, name, ntohs (udpport), ntohs (sec_udpport));

    if ((host = malloc(realm->length + 1)) == NULL)
        return ENOMEM;

    strncpy(host, realm->data, realm->length);
    host[realm->length] = '\0';
    hostlist = 0;

    realm_srv_names[0] = KRB5_CONF_REALMS;
    realm_srv_names[1] = host;
    realm_srv_names[2] = name;
    realm_srv_names[3] = 0;

    code = profile_get_values(context->profile, realm_srv_names, &hostlist);
    free(host);

    if (code) {
        Tprintf ("config file lookup failed: %s\n",
                 error_message(code));
        if (code == PROF_NO_SECTION || code == PROF_NO_RELATION)
            code = 0;
        return code;
    }

    for (i=0; hostlist[i]; i++) {
        int p1, p2;

        host = hostlist[i];
        Tprintf ("entry %d is '%s'\n", i, host);
        /* Find port number, and strip off any excess characters. */
        if (*host == '[' && (cp = strchr(host, ']')))
            cp = cp + 1;
        else
            cp = host + strcspn(host, " \t:");
        port = (*cp == ':') ? cp + 1 : NULL;
        *cp = '\0';

        if (port) {
            unsigned long l;
#ifdef HAVE_STROUL
            char *endptr;
            l = strtoul (port, &endptr, 10);
            if (endptr == NULL || *endptr != 0)
                return EINVAL;
#else
            l = atoi (port);
#endif
            /* L is unsigned, don't need to check <0.  */
            if (l > 65535)
                return EINVAL;
            p1 = htons (l);
            p2 = 0;
        } else {
            p1 = udpport;
            p2 = sec_udpport;
        }

        /* If the hostname was in brackets, strip those off now. */
        if (*host == '[' && (cp = strchr(host, ']'))) {
            host++;
            *cp = '\0';
        }

        code = add_host_to_list(serverlist, host, p1, socktype, AF_UNSPEC);
        /* Second port is for IPv4 UDP only, and should possibly go away as
         * it was originally a krb4 compatibility measure. */
        if (code == 0 && p2 != 0 &&
            (socktype == 0 || socktype == SOCK_DGRAM))
            code = add_host_to_list(serverlist, host, p2, SOCK_DGRAM, AF_INET);
        if (code)
            goto cleanup;
    }

cleanup:
    profile_free_list(hostlist);
    return code;
}
Exemple #9
0
static krb5_error_code
locate_srv_conf_1(krb5_context context, const krb5_data *realm,
                  const char * name, struct serverlist *serverlist,
                  k5_transport transport, int udpport)
{
    const char *realm_srv_names[4];
    char **hostlist = NULL, *realmstr = NULL, *host = NULL;
    const char *hostspec;
    krb5_error_code code;
    int i, default_port;

    Tprintf("looking in krb5.conf for realm %s entry %s; ports %d,%d\n",
            realm->data, name, udpport);

    realmstr = k5memdup0(realm->data, realm->length, &code);
    if (realmstr == NULL)
        goto cleanup;

    realm_srv_names[0] = KRB5_CONF_REALMS;
    realm_srv_names[1] = realmstr;
    realm_srv_names[2] = name;
    realm_srv_names[3] = 0;
    code = profile_get_values(context->profile, realm_srv_names, &hostlist);
    if (code) {
        Tprintf("config file lookup failed: %s\n", error_message(code));
        if (code == PROF_NO_SECTION || code == PROF_NO_RELATION)
            code = 0;
        goto cleanup;
    }

    for (i = 0; hostlist[i]; i++) {
        int port_num;
        k5_transport this_transport = transport;
        const char *uri_path = NULL;

        hostspec = hostlist[i];
        Tprintf("entry %d is '%s'\n", i, hostspec);

        parse_uri_if_https(hostspec, &this_transport, &hostspec, &uri_path);

        default_port = (this_transport == HTTPS) ? 443 : udpport;
        code = k5_parse_host_string(hostspec, default_port, &host, &port_num);
        if (code == 0 && host == NULL)
            code = EINVAL;
        if (code)
            goto cleanup;

        code = add_host_to_list(serverlist, host, port_num, this_transport,
                                AF_UNSPEC, uri_path, -1);
        if (code)
            goto cleanup;

        free(host);
        host = NULL;
    }

cleanup:
    free(realmstr);
    free(host);
    profile_free_list(hostlist);
    return code;
}