void engine::process_filedrop_responce(const std::string& r, report_level s) const
{
    xml::document<> d;
    d.parse<xml::parse_fastest | xml::parse_no_utf8>(const_cast<char*>(r.c_str()));
    if (d.first_node() == 0) {
        throw request_error("filedrop", r);
    }
    std::string h(d.first_node()->name(), d.first_node()->name_size());
    xml::node_iterator<> i(d.first_node());
    xml::node_iterator<> e;
    std::string q;
    while(i != e) {
        std::string n(i->name(), i->name_size());
        if (n == "status") {
            q = std::string(i->value(), i->value_size());
            if (s >= NORMAL) {
                io::mout << q << io::endl;
            }
            break;
        }
        ++i;
    }
    if (q.empty()) {
        throw request_error("filedrop", r);
    }
}
std::string engine::process_create_filelink_responce(const std::string& r, report_level s) const
{
    xml::document<> d;
    d.parse<xml::parse_fastest | xml::parse_no_utf8>(const_cast<char*>(r.c_str()));
    if (d.first_node() == 0) {
        throw request_error("create_filelink", r);
    }
    std::string h(d.first_node()->name(), d.first_node()->name_size());
    xml::node_iterator<> i(d.first_node());
    xml::node_iterator<> e;
    std::string q;
    while(i != e) {
        std::string n(i->name(), i->name_size());
        if (n == "url") {
            q = std::string(i->value(), i->value_size());
            if (s >= NORMAL) {
                io::mout << "Created filelink sucessfully. URL: " << q << io::endl;
            }
            break;
        }
        ++i;
    }
    if (q.empty()) {
        throw request_error("create_filelink", r);
    }
    return q;
}
Exemple #3
0
void winbindd_list_trusted_domains(struct winbindd_cli_state *state)
{
	struct winbindd_tdc_domain *dom_list = NULL;
	struct winbindd_tdc_domain *d = NULL;
	size_t num_domains = 0;
	int extra_data_len = 0;
	char *extra_data = NULL;
	int i = 0;

	DEBUG(3, ("[%5lu]: list trusted domains\n",
		  (unsigned long)state->pid));

	if( !wcache_tdc_fetch_list( &dom_list, &num_domains )) {
		request_error(state);	
		goto done;
	}

	extra_data = talloc_strdup(state->mem_ctx, "");
	if (extra_data == NULL) {
		request_error(state);
		goto done;
	}

	for ( i = 0; i < num_domains; i++ ) {
		struct winbindd_domain *domain;
		bool is_online = true;		

		d = &dom_list[i];
		domain = find_domain_from_name_noinit(d->domain_name);
		if (domain) {
			is_online = domain->online;
		}
		extra_data = talloc_asprintf_append_buffer(
			extra_data,
			"%s\\%s\\%s\\%s\\%s\\%s\\%s\\%s\n",
			d->domain_name,
			d->dns_name ? d->dns_name : d->domain_name,
			sid_string_talloc(state->mem_ctx, &d->sid),
			get_trust_type_string(d),
			trust_is_transitive(d) ? "Yes" : "No",
			trust_is_inbound(d) ? "Yes" : "No",
			trust_is_outbound(d) ? "Yes" : "No",
			is_online ? "Online" : "Offline" );
	}

	extra_data_len = strlen(extra_data);
	if (extra_data_len > 0) {

		/* Strip the last \n */
		extra_data[extra_data_len-1] = '\0';

		state->response->extra_data.data = extra_data;
		state->response->length += extra_data_len;
	}

	request_ok(state);	
done:
	TALLOC_FREE( dom_list );
}
Exemple #4
0
void winbindd_wins_byname(struct winbindd_cli_state *state)
{
	struct sockaddr_storage *ip_list = NULL;
	int i, count, maxlen, size;
	fstring response;
	char addr[INET6_ADDRSTRLEN];

	/* Ensure null termination */
	state->request->data.winsreq[sizeof(state->request->data.winsreq)-1]='\0';

	DEBUG(3, ("[%5lu]: wins_byname %s\n", (unsigned long)state->pid,
		state->request->data.winsreq));

	*response = '\0';
	maxlen = sizeof(response) - 1;

	ip_list = lookup_byname_backend(
		state->mem_ctx, state->request->data.winsreq, &count);
	if (ip_list != NULL){
		for (i = count; i ; i--) {
			print_sockaddr(addr, sizeof(addr), &ip_list[i-1]);
			size = strlen(addr);
			if (size > maxlen) {
				TALLOC_FREE(ip_list);
				request_error(state);
				return;
			}
			if (i != 0) {
				/* Clear out the newline character */
				/* But only if there is something in there,
				otherwise we clobber something in the stack */
				if (strlen(response)) {
					response[strlen(response)-1] = ' ';
				}
			}
			fstrcat(response,addr);
			fstrcat(response,"\t");
		}
		size = strlen(state->request->data.winsreq) + strlen(response);
		if (size > maxlen) {
		    TALLOC_FREE(ip_list);
		    request_error(state);
		    return;
		}
		fstrcat(response,state->request->data.winsreq);
		fstrcat(response,"\n");
		TALLOC_FREE(ip_list);
	} else {
		request_error(state);
		return;
	}

	fstrcpy(state->response->data.winsresp,response);

	request_ok(state);
}
Exemple #5
0
/* return NULL on success, xmlrpc error struct on failure */
xmlrpc_value *
status_set(xmlrpc_env *envP, struct call_info *cip, const char *s)
{
  char *fname = NULL;
  int res = -1;
  if (!cip)
    return request_error(envP, "oracc-xmlrpc: status_get: NULL call_info", NULL);
  if (!cip->session)
    return request_error(envP, "oracc-xmlrpc: status_get: no session set in call_info", NULL);
  fname = status_file(cip);
  fprintf(stderr, "status_set: attempting to set status to %s in %s\n", s, fname);
  if ((res = open(fname, O_WRONLY|O_CREAT|O_TRUNC,S_IRUSR|S_IWUSR)) < 0)
    return request_error(envP, "oracc-xmlrpc: unable to write status for session %s\n%s", cip->session, strerror(errno), NULL);
  if ((res = write(res, s, strlen(s))) < 0)
    return request_error(envP, "oracc-xmlrpc: write of %d bytes failed for session %s\n%s", strlen(s), cip->session, strerror(errno), NULL);
  return NULL;
}
Exemple #6
0
void winbindd_wins_byip(struct winbindd_cli_state *state)
{
	fstring response;
	int i, count, maxlen, size;
	struct node_status *status;

	/* Ensure null termination */
	state->request->data.winsreq[sizeof(state->request->data.winsreq)-1]='\0';

	DEBUG(3, ("[%5lu]: wins_byip %s\n", (unsigned long)state->pid,
		state->request->data.winsreq));

	*response = '\0';
	maxlen = sizeof(response) - 1;

	if ((status = lookup_byaddr_backend(
		     state->mem_ctx, state->request->data.winsreq, &count))) {
	    size = strlen(state->request->data.winsreq);
	    if (size > maxlen) {
		TALLOC_FREE(status);
		request_error(state);
		return;
	    }
	    fstrcat(response,state->request->data.winsreq);
	    fstrcat(response,"\t");
	    for (i = 0; i < count; i++) {
		/* ignore group names */
		if (status[i].flags & 0x80) continue;
		if (status[i].type == 0x20) {
			size = sizeof(status[i].name) + strlen(response);
			if (size > maxlen) {
			    TALLOC_FREE(status);
			    request_error(state);
			    return;
			}
			fstrcat(response, status[i].name);
			fstrcat(response, " ");
		}
	    }
	    /* make last character a newline */
	    response[strlen(response)-1] = '\n';
	    TALLOC_FREE(status);
	}
	fstrcpy(state->response->data.winsresp,response);
	request_ok(state);
}
std::string engine::get_filedrop_api_key(const std::string& url, report_level s, validate_cert v)
{
    init_curl("", s, v);
    curl_easy_setopt(m_curl, CURLOPT_URL, url.c_str());
    curl_header_guard hg(m_curl);
    if (s >= VERBOSE) {
        io::mout << "Getting filedrop API key" << io::endl;
    }
    std::string r = perform();
    xml::document<> d;
    d.parse<xml::parse_fastest | xml::parse_no_utf8>(const_cast<char*>(r.c_str()));
    if (d.first_node() == 0) {
        throw request_error("filedrop info", r);
    }
    std::string h(d.first_node()->name(), d.first_node()->name_size());
    xml::node_iterator<> i(d.first_node());
    xml::node_iterator<> e;
    if (h == "error") {
        while(i != e) {
            std::string n(i->name(), i->name_size());
            if (n == "message") {
                std::string m = std::string(i->value(), i->value_size());
                throw request_error("filedrop info", m);
                break;
            }
            ++i;
        }
        throw request_error("filedrop info", r);
    }
    std::string q;
    while(i != e) {
        std::string n(i->name(), i->name_size());
        if (n == "api_key") {
            q = std::string(i->value(), i->value_size());
            if (s >= VERBOSE) {
                io::mout << "Got filedrop API key: " << q << io::endl;
            }
            break;
        }
        ++i;
    }
    if (q.empty()) {
        throw request_error("filedrop info", r);
    }
    return q;
}
Exemple #8
0
static void stop_flow(struct request_stop_flow *request)
{
	DEBUG_MSG(LOG_DEBUG, "stop_flow forcefully unlocked mutex");
	pthread_mutex_unlock(&mutex);

	if (request->flow_id == -1) {
		/* Stop all flows */

		const struct list_node *node = fg_list_front(&flows);
		while (node) {
			struct flow *flow = node->data;
			node = node->next;

			flow->statistics[FINAL].has_tcp_info =
				get_tcp_info(flow,
					     &flow->statistics[FINAL].tcp_info)
					? 0 : 1;
			flow->pmtu = get_pmtu(flow->fd);

			if (flow->settings.reporting_interval)
				report_flow(flow, INTERVAL);
			report_flow(flow, FINAL);

			uninit_flow(flow);
			remove_flow(flow);
		}

		return;
	}

	const struct list_node *node = fg_list_front(&flows);
	while (node) {
		struct flow *flow = node->data;
		node = node->next;

		if (flow->id != request->flow_id)
			continue;

		/* On Other OSes than Linux or FreeBSD, tcp_info will contain all zeroes */
		flow->statistics[FINAL].has_tcp_info =
			get_tcp_info(flow,
				     &flow->statistics[FINAL].tcp_info)
				? 0 : 1;
		flow->pmtu = get_pmtu(flow->fd);

		if (flow->settings.reporting_interval)
			report_flow(flow, INTERVAL);
		report_flow(flow, FINAL);

		uninit_flow(flow);
		remove_flow(flow);
		return;
	}

	request_error(&request->r, "Unknown flow id");
}
void engine::process_attach_responce(const std::string& r, report_level s) const
{
    if (r.size() == s_normal_id_size) {
        if (s >= NORMAL) {
            io::mout << "File uploaded successfully. ID: " << r << io::endl;
        }
        return;
    }
    throw request_error("upload", r);
}
Exemple #10
0
static void process_requests()
{
	int rc;
	DEBUG_MSG(LOG_DEBUG, "process_requests trying to lock mutex");
	pthread_mutex_lock(&mutex);
	DEBUG_MSG(LOG_DEBUG, "process_requests locked mutex");

	char tmp[100];
	for (;;) {
		int rc = read(daemon_pipe[0], tmp, 100);
		if (rc != 100)
			break;
	}

	while (requests) {
		struct _request* request = requests;
		requests = requests->next;
		rc = 0;

		switch (request->type) {
		case REQUEST_ADD_DESTINATION:
			add_flow_destination((struct
						_request_add_flow_destination
						*)request);
			break;
		case REQUEST_ADD_SOURCE:
			rc = add_flow_source((struct
						_request_add_flow_source
						*)request);
			break;
		case REQUEST_START_FLOWS:
			start_flows((struct _request_start_flows *)request);
			break;
		case REQUEST_STOP_FLOW:
			stop_flow((struct _request_stop_flow *)request);
			break;
		case REQUEST_GET_STATUS:
			{
				struct _request_get_status *r =
					(struct _request_get_status *)request;
				r->started = started;
				r->num_flows = num_flows;
			}
			break;
		default:
			request_error(request, "Unknown request type");
			break;
		}
		if (rc != 1)
			pthread_cond_signal(request->condition);
	}

	pthread_mutex_unlock(&mutex);
	DEBUG_MSG(LOG_DEBUG, "process_requests unlocked mutex");
}
Exemple #11
0
void winbindd_ccache_save(struct winbindd_cli_state *state)
{
	struct winbindd_domain *domain;
	fstring name_domain, name_user;

	/* Ensure null termination */
	state->request->data.ccache_save.user[
		sizeof(state->request->data.ccache_save.user)-1]='\0';
	state->request->data.ccache_save.pass[
		sizeof(state->request->data.ccache_save.pass)-1]='\0';

	DEBUG(3, ("[%5lu]: save password of user %s\n",
		  (unsigned long)state->pid,
		  state->request->data.ccache_save.user));

	/* Parse domain and username */

	if (!canonicalize_username(state->request->data.ccache_ntlm_auth.user,
				   name_domain, name_user)) {
		DEBUG(5,("winbindd_ccache_save: cannot parse domain and user "
			 "from name [%s]\n",
			 state->request->data.ccache_save.user));
		request_error(state);
		return;
	}

	domain = find_auth_domain(state->request->flags, name_domain);

	if (domain == NULL) {
		DEBUG(5, ("winbindd_ccache_save: can't get domain [%s]\n",
			  name_domain));
		request_error(state);
		return;
	}

	if (!check_client_uid(state, state->request->data.ccache_save.uid)) {
		request_error(state);
		return;
	}

	sendto_domain(state, domain);
}
Exemple #12
0
static void stop_flow(struct _request_stop_flow *request)
{
	DEBUG_MSG(LOG_DEBUG, "stop_flow forcefully unlocked mutex");
	pthread_mutex_unlock(&mutex);

	if (request->flow_id == -1) {
		/* Stop all flows */

		for (unsigned int i = 0; i < num_flows; i++) {
			struct _flow *flow = &flows[i];

			flow->statistics[FINAL].has_tcp_info =
				get_tcp_info(flow,
					     &flow->statistics[FINAL].tcp_info)
					? 0 : 1;
			flow->pmtu = get_pmtu(flow->fd);

			if (flow->settings.reporting_interval)
				report_flow(flow, INTERVAL);
			report_flow(flow, FINAL);

			uninit_flow(flow);
			remove_flow(i);
		}

		return;
	}

	for (unsigned int i = 0; i < num_flows; i++) {
		struct _flow *flow = &flows[i];

		if (flow->id != request->flow_id)
			continue;

		/* On Other OSes than Linux or FreeBSD, tcp_info will contain all zeroes */
		flow->statistics[FINAL].has_tcp_info =
			get_tcp_info(flow,
				     &flow->statistics[FINAL].tcp_info)
				? 0 : 1;
		flow->pmtu = get_pmtu(flow->fd);

		if (flow->settings.reporting_interval)
			report_flow(flow, INTERVAL);
		report_flow(flow, FINAL);

		uninit_flow(flow);
		remove_flow(i);
		return;
	}

	request_error(&request->r, "Unknown flow id");
}
std::string engine::process_get_api_key_responce(const std::string& r, report_level s) const
{
    xml::document<> d;
    d.parse<xml::parse_fastest | xml::parse_no_utf8>(const_cast<char*>(r.c_str()));
    if (d.first_node() == 0) {
        throw request_error("get_api_key", r);
    }
    std::string h(d.first_node()->name(), d.first_node()->name_size());
    xml::node_iterator<> i(d.first_node());
    xml::node_iterator<> e;
    if (h == "error") {
        while(i != e) {
            std::string n(i->name(), i->name_size());
            if (n == "message") {
                std::string m = std::string(i->value(), i->value_size());
                throw request_error("get_api_key", m);
                break;
            }
            ++i;
        }
        throw request_error("get_api_key", r);
    }
    std::string q;
    while(i != e) {
        std::string n(i->name(), i->name_size());
        if (n == "api_key") {
            q = std::string(i->value(), i->value_size());
            if (s >= NORMAL) {
                io::mout << "Retrieved API key: " << q << io::endl;
            }
            break;
        }
        ++i;
    }
    if (q.empty()) {
        throw request_error("get_api_key", r);
    }
    return q;
}
Exemple #14
0
/* return xmlrpc status struct on success, xmlrpc error struct on failure */
xmlrpc_value *
status_get(xmlrpc_env * envP, struct call_info *cip)
{
  char *fname = NULL, *buf = NULL;
  int res = -1;
  struct stat st;
  xmlrpc_value *s;

  trace();
  if (!cip)
    return request_error(envP, "oracc-xmlrpc: status_get: NULL call_info", NULL);
  trace();
  if (!cip->session)
    return request_error(envP, "oracc-xmlrpc: status_get: no session set in call_info", NULL);
  trace();
  fname = status_file(cip);
  if ((res = stat(fname, &st)) < 0)
    return request_error(envP, "oracc-xmlrpc: unable to stat status for session %s\n%s", cip->session, strerror(errno), NULL);
  trace();
  buf = malloc((size_t)st.st_size + 1);
  if ((res = open(fname, O_RDONLY)) < 0)
    return request_error(envP, "oracc-xmlrpc: unable to read status for session %s\n%s", cip->session, strerror(errno), NULL);
  trace();
  if ((res = read(res, buf, st.st_size)) < 0)
    return request_error(envP, "oracc-xmlrpc: read of %d bytes failed for session %s\n%s", (int)st.st_size, cip->session, strerror(errno), NULL);
  buf[st.st_size] = '\0';
  fprintf(stderr, "status_get: read status `%s'\n", buf);
  trace();
  s = request_status(envP, "OK", NULL);

  if (!strcmp(buf, "completed"))
    method_files(envP, s);

  method_status(envP, s, "%s", buf, NULL);
  return s;
}
void engine::process_attach_chunk_responce(const std::string& r, report_level s) const
{
    if (r.empty() || r == " ") {
        if (s >= NORMAL) {
            io::mout << "Current chunk uploaded successfully." << io::endl;
        }
        return;
    }
    if (r.size() == s_normal_id_size) {
        if (s >= NORMAL) {
            io::mout << "All chunks of file uploaded successfully. ID: " << r << io::endl;
        }
        return;
    }
    throw request_error("upload_chunk", r);
}
std::string engine::process_send_responce(const std::string& r,
        report_level s) const
{
    xml::document<> d;
    d.parse<xml::parse_fastest | xml::parse_no_utf8>(const_cast<char*>(r.c_str()));
    xml::node_iterator<> i(d.first_node());
    xml::node_iterator<> e;
    while(i != e) {
        std::string n(i->name(), i->name_size());
        if (n == "id") {
            std::string v(i->value(), i->value_size());
            if (s >= NORMAL) {
                io::mout << "Message sent successfully. ID: " << v << io::endl;
            }
            return v;
        }
        ++i;
    }
    throw request_error("send", r);
    return "";
}
void engine::delete_filelink(std::string server,
            const std::string& key,
            const std::string& id,
            report_level s,
            validate_cert v)
{
    init_curl(key, s, v);
    server += "/link/";
    server += id;
    curl_easy_setopt(m_curl, CURLOPT_URL, server.c_str());
    curl_header_guard hg(m_curl);
    curl_easy_setopt(m_curl, CURLOPT_CUSTOMREQUEST, "DELETE");
    if (s >= NORMAL) {
        io::mout << "Deleting filelink with id '" << id << "'" << io::endl;
    }
    std::string r = perform();
    if (r.find_first_not_of(' ') != r.npos) {
        throw request_error("delete_filelink", r);
    }
    io::mout << "Filelink deleted successfully." << io::endl;
}
Exemple #18
0
static int dispatch_request(struct _request *request, int type)
{
	pthread_cond_t cond;

	request->error = NULL;
	request->type = type;
	request->next = NULL;

	/* Create synchronization mutex */
	if (pthread_cond_init(&cond, NULL)) {
		request_error(request, "Could not create synchronization mutex");
		return -1;
	}
	request->condition = &cond;

	pthread_mutex_lock(&mutex);

	if (!requests) {
		requests = request;
		requests_last = request;
	}
	else {
		requests_last->next = request;
		requests_last = request;
	}
	if ( write(daemon_pipe[1], &type, 1) != 1 ) /* Doesn't matter what we write */
		return -1;
	/* Wait until the daemon thread has processed the request */
	pthread_cond_wait(&cond, &mutex);

	pthread_mutex_unlock(&mutex);

	if (request->error)
		return -1;

	return 0;
}
Exemple #19
0
int add_flow_source(struct _request_add_flow_source *request)
{
#ifdef TCP_CONGESTION
    socklen_t opt_len = 0;
#endif /* TCP_CONGESTION */
    struct _flow *flow;

    if (num_flows >= MAX_FLOWS) {
        logging_log(LOG_WARNING, "Can not accept another flow, already handling MAX_FLOW flows.");
        request_error(&request->r, "Can not accept another flow, already handling MAX_FLOW flows.");
        return -1;
    }

    flow = &flows[num_flows++];
    init_flow(flow, 1);

    flow->settings = request->settings;
    flow->source_settings = request->source_settings;
    /* be greedy with buffer sizes */
    flow->write_block = calloc(1, flow->settings.maximum_block_size);
    flow->read_block = calloc(1, flow->settings.maximum_block_size);

    if (flow->write_block == NULL || flow->read_block == NULL) {
        logging_log(LOG_ALERT, "could not allocate memory for read/write blocks");
        request_error(&request->r, "could not allocate memory for read/write blocks");
        uninit_flow(flow);
        num_flows--;
        return -1;
    }
    if (flow->settings.byte_counting) {
        int byte_idx;
        for (byte_idx = 0; byte_idx < flow->settings.maximum_block_size; byte_idx++)
            *(flow->write_block + byte_idx) = (unsigned char)(byte_idx & 0xff);
    }

    flow->state = GRIND_WAIT_CONNECT;
    flow->fd = name2socket(flow, flow->source_settings.destination_host,
                           flow->source_settings.destination_port,
                           &flow->addr, &flow->addr_len, 0,
                           flow->settings.requested_read_buffer_size, &request->real_read_buffer_size,
                           flow->settings.requested_send_buffer_size, &request->real_send_buffer_size);
    if (flow->fd == -1) {
        logging_log(LOG_ALERT, "Could not create data socket: %s", flow->error);
        request_error(&request->r, "Could not create data socket: %s", flow->error);
        uninit_flow(flow);
        num_flows--;
        return -1;
    }

    if (set_flow_tcp_options(flow) == -1) {
        request->r.error = flow->error;
        flow->error = NULL;
        uninit_flow(flow);
        num_flows--;
        return -1;
    }

#ifdef TCP_CONGESTION
    opt_len = sizeof(request->cc_alg);
    if (getsockopt(flow->fd, IPPROTO_TCP, TCP_CONGESTION,
                   request->cc_alg, &opt_len) == -1) {
        request_error(&request->r, "failed to determine actual congestion control algorithm: %s",
                      strerror(errno));
        uninit_flow(flow);
        num_flows--;
        return -1;
    }
#endif /* TCP_CONGESTION */

#ifdef HAVE_LIBPCAP
    fg_pcap_go(flow);
#endif /* HAVE_LIBPCAP */
    if (!flow->source_settings.late_connect) {
        DEBUG_MSG(4, "(early) connecting test socket");
        connect(flow->fd, flow->addr, flow->addr_len);
        flow->connect_called = 1;
        flow->pmtu = get_pmtu(flow->fd);
    }

    request->flow_id = flow->id;

    return 0;
}
void winbindd_ccache_save(struct winbindd_cli_state *state)
{
	struct winbindd_domain *domain;
	fstring name_domain, name_user;
	NTSTATUS status;

	/* Ensure null termination */
	state->request->data.ccache_save.user[
		sizeof(state->request->data.ccache_save.user)-1]='\0';
	state->request->data.ccache_save.pass[
		sizeof(state->request->data.ccache_save.pass)-1]='\0';

	DEBUG(3, ("[%5lu]: save password of user %s\n",
		  (unsigned long)state->pid,
		  state->request->data.ccache_save.user));

	/* Parse domain and username */

	if (!canonicalize_username(state->request->data.ccache_save.user,
				   name_domain, name_user)) {
		DEBUG(5,("winbindd_ccache_save: cannot parse domain and user "
			 "from name [%s]\n",
			 state->request->data.ccache_save.user));
		request_error(state);
		return;
	}

	/*
	 * The domain is checked here only for compatibility
	 * reasons. We used to do the winbindd memory ccache for
	 * ntlm_auth in the domain child. With that code, we had to
	 * make sure that we do have a domain around to send this
	 * to. Now we do the memory cache in the parent winbindd,
	 * where it would not matter if we have a domain or not.
	 */

	domain = find_auth_domain(state->request->flags, name_domain);
	if (domain == NULL) {
		DEBUG(5, ("winbindd_ccache_save: can't get domain [%s]\n",
			  name_domain));
		request_error(state);
		return;
	}

	if (!check_client_uid(state, state->request->data.ccache_save.uid)) {
		request_error(state);
		return;
	}

	status = winbindd_add_memory_creds(
		state->request->data.ccache_save.user,
		state->request->data.ccache_save.uid,
		state->request->data.ccache_save.pass);

	if (!NT_STATUS_IS_OK(status)) {
		DEBUG(1, ("winbindd_add_memory_creds failed %s\n",
			  nt_errstr(status)));
		request_error(state);
		return;
	}
	request_ok(state);
}
void winbindd_ccache_ntlm_auth(struct winbindd_cli_state *state)
{
	struct winbindd_domain *domain;
	fstring name_domain, name_user;
	NTSTATUS result = NT_STATUS_NOT_SUPPORTED;
	struct WINBINDD_MEMORY_CREDS *entry;
	DATA_BLOB initial, challenge, auth;
	uint32_t initial_blob_len, challenge_blob_len, extra_len;

	/* Ensure null termination */
	state->request->data.ccache_ntlm_auth.user[
			sizeof(state->request->data.ccache_ntlm_auth.user)-1]='\0';

	DEBUG(3, ("[%5lu]: perform NTLM auth on behalf of user %s\n", (unsigned long)state->pid,
		state->request->data.ccache_ntlm_auth.user));

	/* Parse domain and username */

	if (!canonicalize_username(state->request->data.ccache_ntlm_auth.user,
				name_domain, name_user)) {
		DEBUG(5,("winbindd_ccache_ntlm_auth: cannot parse domain and user from name [%s]\n",
			state->request->data.ccache_ntlm_auth.user));
		request_error(state);
		return;
	}

	domain = find_auth_domain(state->request->flags, name_domain);

	if (domain == NULL) {
		DEBUG(5,("winbindd_ccache_ntlm_auth: can't get domain [%s]\n",
			name_domain));
		request_error(state);
		return;
	}

	if (!check_client_uid(state, state->request->data.ccache_ntlm_auth.uid)) {
		request_error(state);
		return;
	}

	/* validate blob lengths */
	initial_blob_len = state->request->data.ccache_ntlm_auth.initial_blob_len;
	challenge_blob_len = state->request->data.ccache_ntlm_auth.challenge_blob_len;
	extra_len = state->request->extra_len;

	if (initial_blob_len > extra_len || challenge_blob_len > extra_len ||
		initial_blob_len + challenge_blob_len > extra_len ||
		initial_blob_len + challenge_blob_len < initial_blob_len ||
		initial_blob_len + challenge_blob_len < challenge_blob_len) {

		DEBUG(10,("winbindd_dual_ccache_ntlm_auth: blob lengths overrun "
			"or wrap. Buffer [%d+%d > %d]\n",
			initial_blob_len,
			challenge_blob_len,
			extra_len));
		goto process_result;
	}

	/* Parse domain and username */
	if (!parse_domain_user(state->request->data.ccache_ntlm_auth.user, name_domain, name_user)) {
		DEBUG(10,("winbindd_dual_ccache_ntlm_auth: cannot parse "
			"domain and user from name [%s]\n",
			state->request->data.ccache_ntlm_auth.user));
		goto process_result;
	}

	entry = find_memory_creds_by_name(state->request->data.ccache_ntlm_auth.user);
	if (entry == NULL || entry->nt_hash == NULL || entry->lm_hash == NULL) {
		DEBUG(10,("winbindd_dual_ccache_ntlm_auth: could not find "
			"credentials for user %s\n", 
			state->request->data.ccache_ntlm_auth.user));
		goto process_result;
	}

	DEBUG(10,("winbindd_dual_ccache_ntlm_auth: found ccache [%s]\n", entry->username));

	if (!client_can_access_ccache_entry(state->request->data.ccache_ntlm_auth.uid, entry)) {
		goto process_result;
	}

	if (initial_blob_len == 0 && challenge_blob_len == 0) {
		/* this is just a probe to see if credentials are available. */
		result = NT_STATUS_OK;
		state->response->data.ccache_ntlm_auth.auth_blob_len = 0;
		goto process_result;
	}

	initial = data_blob_const(state->request->extra_data.data,
				  initial_blob_len);
	challenge = data_blob_const(
		state->request->extra_data.data + initial_blob_len,
		state->request->data.ccache_ntlm_auth.challenge_blob_len);

	result = do_ntlm_auth_with_stored_pw(
		name_user, name_domain, entry->pass,
		initial, challenge, &auth,
		state->response->data.ccache_ntlm_auth.session_key);

	if (!NT_STATUS_IS_OK(result)) {
		goto process_result;
	}

	state->response->extra_data.data = talloc_memdup(
		state->mem_ctx, auth.data, auth.length);
	if (!state->response->extra_data.data) {
		result = NT_STATUS_NO_MEMORY;
		goto process_result;
	}
	state->response->length += auth.length;
	state->response->data.ccache_ntlm_auth.auth_blob_len = auth.length;

	data_blob_free(&auth);

  process_result:
	if (!NT_STATUS_IS_OK(result)) {
		request_error(state);
		return;
	}
	request_ok(state);
}
Exemple #22
0
static void execrline(void *arg) {
  struct sched_rline *sr = arg;
  int re, i;
  char *argv[XMAXARGS], *buf;

  sr->schedule = NULL;

  buf = sr->argv;
  for(i=0;i<sr->argc;i++) {
    argv[i] = buf;
    buf+=strlen(buf) + 1;
  }

  re = (sr->hl->function)(&sr->rl, sr->argc, argv);

  if(re)
    Error("nterfacer", ERR_WARNING, "sendline: error occured calling %p %d: %s", sr->hl->function, re, request_error(re));
}
Exemple #23
0
int nterfacer_line_event(struct esocket *sock, char *newline) {
  struct sconnect *socket = sock->tag;
  char *response, *theirnonceh = NULL, *theirivh = NULL;
  unsigned char theirnonce[16], theiriv[16];
  int number, reason;

  switch(socket->status) {
    case SS_IDLE:
      if(strcasecmp(newline, ANTI_FULL_VERSION)) {
        nterface_log(nrl, NL_INFO, "Protocol mismatch from %s: %s", socket->permit->hostname->content, newline);
        return 1;
      } else {
        unsigned char challenge[32];
        char ivhex[16 * 2 + 1], noncehex[16 * 2 + 1];

        if(!get_entropy(challenge, 32) || !get_entropy(socket->iv, 16)) {
          nterface_log(nrl, NL_ERROR, "Unable to open challenge/IV entropy bin!");
          return 1;
        }

        int_to_hex(challenge, socket->challenge, 32);
        int_to_hex(socket->iv, ivhex, 16);

        memcpy(socket->response, challenge_response(socket->challenge, socket->permit->password->content), sizeof(socket->response));
        socket->response[sizeof(socket->response) - 1] = '\0'; /* just in case */

        socket->status = SS_VERSIONED;
        if(!generate_nonce(socket->ournonce, 1)) {
          nterface_log(nrl, NL_ERROR, "Unable to generate nonce!");
          return 1;
        }
        int_to_hex(socket->ournonce, noncehex, 16);

        if(esocket_write_line(sock, "%s %s %s", socket->challenge, ivhex, noncehex))
           return BUF_ERROR;
        return 0;
      }
      break;
    case SS_VERSIONED:
      for(response=newline;*response;response++) {
        if((*response == ' ') && (*(response + 1))) {
          *response = '\0';
          theirivh = response + 1;
          break;
        }
      }

      if(theirivh) {
        for(response=theirivh;*response;response++) {
          if((*response == ' ') && (*(response + 1))) {
            *response = '\0';
            theirnonceh = response + 1;
            break;
          }
        }
      }

      if(!theirivh || (strlen(theirivh) != 32) || !hex_to_int(theirivh, theiriv, sizeof(theiriv)) ||
         !theirnonceh || (strlen(theirnonceh) != 32) || !hex_to_int(theirnonceh, theirnonce, sizeof(theirnonce))) {
        nterface_log(nrl, NL_INFO, "Protocol error drop: %s", socket->permit->hostname->content);
        return 1;
      }

      if(!memcmp(socket->ournonce, theirnonce, sizeof(theirnonce))) {
        nterface_log(nrl, NL_INFO, "Bad nonce drop: %s", socket->permit->hostname->content);
        return 1;
      }

      if(!strncasecmp(newline, socket->response, sizeof(socket->response))) {
        unsigned char theirkey[32], ourkey[32];

        derive_key(ourkey, socket->permit->password->content, socket->challenge, socket->ournonce, theirnonce, (unsigned char *)"SERVER", 6);

        derive_key(theirkey, socket->permit->password->content, socket->response, theirnonce, socket->ournonce, (unsigned char *)"CLIENT", 6);
        nterface_log(nrl, NL_INFO, "Authed: %s", socket->permit->hostname->content);
        socket->status = SS_AUTHENTICATED;
        switch_buffer_mode(sock, ourkey, socket->iv, theirkey, theiriv);

        if(esocket_write_line(sock, "Oauth"))
          return BUF_ERROR;
      } else {
        nterface_log(nrl, NL_INFO, "Bad CR drop: %s", socket->permit->hostname->content);
        
        return 1;
      }
      break;
    case SS_AUTHENTICATED:
      nterface_log(nrl, NL_INFO|NL_LOG_ONLY, "L(%s): %s", socket->permit->hostname->content, newline);
      reason = nterfacer_new_rline(newline, sock, &number);
      if(reason) {
        if(reason == RE_SOCKET_ERROR)
          return BUF_ERROR;
        if(reason != RE_BAD_LINE) {
          if(esocket_write_line(sock, "%d,E%d,%s", number, reason, request_error(reason)))
            return BUF_ERROR;
          return 0;
        } else {
          return 1;
        }
      }
      break;
  }

  return 0;
}