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; }
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 ); }
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); }
/* 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; }
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; }
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); }
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"); }
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); }
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; }
/* 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; }
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; }
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); }
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)); }
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; }