int setup_ntlmv2_rsp(struct cifsSesInfo *ses, const struct nls_table *nls_cp) { int rc; int baselen; unsigned int tilen; struct ntlmv2_resp *buf; char ntlmv2_hash[16]; unsigned char *tiblob = NULL; /* target info blob */ if (ses->server->secType == RawNTLMSSP) { if (!ses->domainName) { rc = find_domain_name(ses, nls_cp); if (rc) { cERROR(1, "error %d finding domain name", rc); goto setup_ntlmv2_rsp_ret; } } } else { rc = build_avpair_blob(ses, nls_cp); if (rc) { cERROR(1, "error %d building av pair blob", rc); goto setup_ntlmv2_rsp_ret; } } baselen = CIFS_SESS_KEY_SIZE + sizeof(struct ntlmv2_resp); tilen = ses->auth_key.len; tiblob = ses->auth_key.response; ses->auth_key.response = kmalloc(baselen + tilen, GFP_KERNEL); if (!ses->auth_key.response) { rc = ENOMEM; ses->auth_key.len = 0; cERROR(1, "%s: Can't allocate auth blob", __func__); goto setup_ntlmv2_rsp_ret; } ses->auth_key.len += baselen; buf = (struct ntlmv2_resp *) (ses->auth_key.response + CIFS_SESS_KEY_SIZE); buf->blob_signature = cpu_to_le32(0x00000101); buf->reserved = 0; buf->time = cpu_to_le64(cifs_UnixTimeToNT(CURRENT_TIME)); get_random_bytes(&buf->client_chal, sizeof(buf->client_chal)); buf->reserved2 = 0; memcpy(ses->auth_key.response + baselen, tiblob, tilen); /* calculate ntlmv2_hash */ rc = calc_ntlmv2_hash(ses, ntlmv2_hash, nls_cp); if (rc) { cERROR(1, "could not get v2 hash rc %d", rc); goto setup_ntlmv2_rsp_ret; } /* calculate first part of the client response (CR1) */ rc = CalcNTLMv2_response(ses, ntlmv2_hash); if (rc) { cERROR(1, "Could not calculate CR1 rc: %d", rc); goto setup_ntlmv2_rsp_ret; } /* now calculate the session key for NTLMv2 */ crypto_shash_setkey(ses->server->secmech.hmacmd5, ntlmv2_hash, CIFS_HMAC_MD5_HASH_SIZE); rc = crypto_shash_init(&ses->server->secmech.sdeschmacmd5->shash); if (rc) { cERROR(1, "%s: Could not init hmacmd5\n", __func__); goto setup_ntlmv2_rsp_ret; } crypto_shash_update(&ses->server->secmech.sdeschmacmd5->shash, ses->auth_key.response + CIFS_SESS_KEY_SIZE, CIFS_HMAC_MD5_HASH_SIZE); rc = crypto_shash_final(&ses->server->secmech.sdeschmacmd5->shash, ses->auth_key.response); setup_ntlmv2_rsp_ret: kfree(tiblob); return rc; }
static void build_domains(Postprocessor *pp, Linkage sublinkage) { size_t link, i, d; const char *s; PP_data *pp_data = &pp->pp_data; pp_data->N_domains = 0; for (link = 0; link<sublinkage->num_links; link++) { assert (sublinkage->link_array[link].lw != SIZE_MAX); if (NULL == sublinkage->link_array[link].link_name) continue; s = sublinkage->link_array[link].link_name; if (pp_linkset_match(pp->knowledge->ignore_these_links, s)) continue; if (pp_linkset_match(pp->knowledge->domain_starter_links, s)) { setup_domain_array(pp, s, link); if (pp_linkset_match(pp->knowledge->domain_contains_links, s)) add_link_to_domain(pp_data, link); clear_visited(pp_data); depth_first_search(pp, sublinkage, sublinkage->link_array[link].rw, sublinkage->link_array[link].lw, link); } else if (pp_linkset_match(pp->knowledge->urfl_domain_starter_links, s)) { setup_domain_array(pp, s, link); /* always add the starter link to its urfl domain */ add_link_to_domain(pp_data, link); clear_visited(pp_data); bad_depth_first_search(pp, sublinkage,sublinkage->link_array[link].rw, sublinkage->link_array[link].lw, link); } else if (pp_linkset_match(pp->knowledge->urfl_only_domain_starter_links, s)) { setup_domain_array(pp, s, link); /* do not add the starter link to its urfl_only domain */ clear_visited(pp_data); d_depth_first_search(pp, sublinkage, sublinkage->link_array[link].lw, sublinkage->link_array[link].lw, sublinkage->link_array[link].rw, link); } else if (pp_linkset_match(pp->knowledge->left_domain_starter_links, s)) { setup_domain_array(pp, s, link); /* do not add the starter link to a left domain */ clear_visited(pp_data); left_depth_first_search(pp, sublinkage, sublinkage->link_array[link].lw, sublinkage->link_array[link].rw, link); } } /* sort the domains by size */ qsort((void *) pp_data->domain_array, pp_data->N_domains, sizeof(Domain), (int (*)(const void *, const void *)) domain_compare); /* sanity check: all links in all domains have a legal domain name */ for (d = 0; d < pp_data->N_domains; d++) { i = find_domain_name(pp, pp_data->domain_array[d].string); if (i == SIZE_MAX) prt_error("Error: post_process(): Need an entry for %s in LINK_TYPE_TABLE", pp_data->domain_array[d].string); pp_data->domain_array[d].type = i; } }
static void build_domains(Postprocessor *pp, Sublinkage *sublinkage) { int link, i, d; char *s; pp->pp_data.N_domains = 0; for (link = 0; link<sublinkage->num_links; link++) { if (sublinkage->link[link]->l == -1) continue; s = sublinkage->link[link]->name; if (pp_linkset_match(pp->knowledge->ignore_these_links, s)) continue; if (pp_linkset_match(pp->knowledge->domain_starter_links, s)) { setup_domain_array(pp, pp->pp_data.N_domains, s, link); if (pp_linkset_match(pp->knowledge->domain_contains_links, s)) add_link_to_domain(pp, link); depth_first_search(pp,sublinkage,sublinkage->link[link]->r, sublinkage->link[link]->l, link); pp->pp_data.N_domains++; assert(pp->pp_data.N_domains<PP_MAX_DOMAINS, "raise value of PP_MAX_DOMAINS"); } else { if (pp_linkset_match(pp->knowledge->urfl_domain_starter_links,s)) { setup_domain_array(pp, pp->pp_data.N_domains, s, link); /* always add the starter link to its urfl domain */ add_link_to_domain(pp, link); bad_depth_first_search(pp,sublinkage,sublinkage->link[link]->r, sublinkage->link[link]->l,link); pp->pp_data.N_domains++; assert(pp->pp_data.N_domains<PP_MAX_DOMAINS,"raise PP_MAX_DOMAINS value"); } else if (pp_linkset_match(pp->knowledge->urfl_only_domain_starter_links,s)) { setup_domain_array(pp, pp->pp_data.N_domains, s, link); /* do not add the starter link to its urfl_only domain */ d_depth_first_search(pp,sublinkage, sublinkage->link[link]->l, sublinkage->link[link]->l, sublinkage->link[link]->r,link); pp->pp_data.N_domains++; assert(pp->pp_data.N_domains<PP_MAX_DOMAINS,"raise PP_MAX_DOMAINS value"); } else if (pp_linkset_match(pp->knowledge->left_domain_starter_links,s)) { setup_domain_array(pp, pp->pp_data.N_domains, s, link); /* do not add the starter link to a left domain */ left_depth_first_search(pp,sublinkage, sublinkage->link[link]->l, sublinkage->link[link]->r,link); pp->pp_data.N_domains++; assert(pp->pp_data.N_domains<PP_MAX_DOMAINS,"raise PP_MAX_DOMAINS value"); } } } /* sort the domains by size */ qsort((void *) pp->pp_data.domain_array, pp->pp_data.N_domains, sizeof(Domain), (int (*)(const void *, const void *)) domain_compare); /* sanity check: all links in all domains have a legal domain name */ for (d=0; d<pp->pp_data.N_domains; d++) { i = find_domain_name(pp, pp->pp_data.domain_array[d].string); if (i==-1) error("\tpost_process: Need an entry for %s in LINK_TYPE_TABLE", pp->pp_data.domain_array[d].string); pp->pp_data.domain_array[d].type = i; } }