static const uint8 *get_ntlm_challenge(struct auth_context *auth_context) { DATA_BLOB challenge = data_blob(NULL, 0); const char *challenge_set_by = NULL; auth_methods *auth_method; TALLOC_CTX *mem_ctx; if (auth_context->challenge.length) { DEBUG(5, ("get_ntlm_challenge (auth subsystem): returning previous challenge by module %s (normal)\n", auth_context->challenge_set_by)); return auth_context->challenge.data; } auth_context->challenge_may_be_modified = False; for (auth_method = auth_context->auth_method_list; auth_method; auth_method = auth_method->next) { if (auth_method->get_chal == NULL) { DEBUG(5, ("auth_get_challenge: module %s did not want to specify a challenge\n", auth_method->name)); continue; } DEBUG(5, ("auth_get_challenge: getting challenge from module %s\n", auth_method->name)); if (challenge_set_by != NULL) { DEBUG(1, ("auth_get_challenge: CONFIGURATION ERROR: authentication method %s has already specified a challenge. Challenge by %s ignored.\n", challenge_set_by, auth_method->name)); continue; } mem_ctx = talloc_init("auth_get_challenge for module %s", auth_method->name); if (!mem_ctx) { smb_panic("talloc_init() failed!"); } challenge = auth_method->get_chal(auth_context, &auth_method->private_data, mem_ctx); if (!challenge.length) { DEBUG(3, ("auth_get_challenge: getting challenge from authentication method %s FAILED.\n", auth_method->name)); } else { DEBUG(5, ("auth_get_challenge: sucessfully got challenge from module %s\n", auth_method->name)); auth_context->challenge = challenge; challenge_set_by = auth_method->name; auth_context->challenge_set_method = auth_method; } talloc_destroy(mem_ctx); } if (!challenge_set_by) { uchar chal[8]; generate_random_buffer(chal, sizeof(chal)); auth_context->challenge = data_blob_talloc(auth_context->mem_ctx, chal, sizeof(chal)); challenge_set_by = "random"; auth_context->challenge_may_be_modified = True; } DEBUG(5, ("auth_context challenge created by %s\n", challenge_set_by)); DEBUG(5, ("challenge is: \n")); dump_data(5, (const char *)auth_context->challenge.data, auth_context->challenge.length); SMB_ASSERT(auth_context->challenge.length == 8); auth_context->challenge_set_by=challenge_set_by; return auth_context->challenge.data; }
bool cli_oem_change_password(struct cli_state *cli, const char *user, const char *new_password, const char *old_password) { char param[1024]; unsigned char data[532]; char *p = param; unsigned char old_pw_hash[16]; unsigned char new_pw_hash[16]; unsigned int data_len; unsigned int param_len = 0; char *rparam = NULL; char *rdata = NULL; unsigned int rprcnt, rdrcnt; if (strlen(user) >= sizeof(fstring)-1) { DEBUG(0,("cli_oem_change_password: user name %s is too long.\n", user)); return False; } SSVAL(p,0,214); /* SamOEMChangePassword command. */ p += 2; strlcpy(p, "zsT", sizeof(param)-PTR_DIFF(p,param)); p = skip_string(param,sizeof(param),p); strlcpy(p, "B516B16", sizeof(param)-PTR_DIFF(p,param)); p = skip_string(param,sizeof(param),p); strlcpy(p,user, sizeof(param)-PTR_DIFF(p,param)); p = skip_string(param,sizeof(param),p); SSVAL(p,0,532); p += 2; param_len = PTR_DIFF(p,param); /* * Get the Lanman hash of the old password, we * use this as the key to make_oem_passwd_hash(). */ E_deshash(old_password, old_pw_hash); encode_pw_buffer(data, new_password, STR_ASCII); #ifdef DEBUG_PASSWORD DEBUG(100,("make_oem_passwd_hash\n")); dump_data(100, data, 516); #endif arcfour_crypt( (unsigned char *)data, (unsigned char *)old_pw_hash, 516); /* * Now place the old password hash in the data. */ E_deshash(new_password, new_pw_hash); E_old_pw_hash( new_pw_hash, old_pw_hash, (uchar *)&data[516]); data_len = 532; if (!cli_api(cli, param, param_len, 4, /* param, length, max */ (char *)data, data_len, 0, /* data, length, max */ &rparam, &rprcnt, &rdata, &rdrcnt)) { DEBUG(0,("cli_oem_change_password: Failed to send password change for user %s\n", user )); return False; } if (rparam) { cli->rap_error = SVAL(rparam,0); } SAFE_FREE(rparam); SAFE_FREE(rdata); return (cli->rap_error == 0); }
static BOOL rpc_auth_pipe(struct cli_state *cli, prs_struct *rdata, uint32 fragment_start, int len, int auth_len, uint8 pkt_type, int *pauth_padding_len) { /* * The following is that length of the data we must sign or seal. * This doesn't include the RPC headers or the auth_len or the RPC_HDR_AUTH_LEN * preceeding the auth_data. */ int data_len = len - RPC_HEADER_LEN - RPC_HDR_RESP_LEN - RPC_HDR_AUTH_LEN - auth_len; /* * The start of the data to sign/seal is just after the RPC headers. */ char *reply_data = prs_data_p(rdata) + fragment_start + RPC_HEADER_LEN + RPC_HDR_REQ_LEN; RPC_HDR_AUTH rhdr_auth; char *dp = prs_data_p(rdata) + fragment_start + len - RPC_HDR_AUTH_LEN - auth_len; prs_struct auth_verf; *pauth_padding_len = 0; if (auth_len == 0) { if (cli->pipe_auth_flags == 0) { /* move along, nothing to see here */ return True; } DEBUG(2, ("No authenticaton header recienved on reply, but this pipe is authenticated\n")); return False; } DEBUG(5,("rpc_auth_pipe: pkt_type: %d len: %d auth_len: %d NTLMSSP %s schannel %s sign %s seal %s \n", pkt_type, len, auth_len, BOOLSTR(cli->pipe_auth_flags & AUTH_PIPE_NTLMSSP), BOOLSTR(cli->pipe_auth_flags & AUTH_PIPE_NETSEC), BOOLSTR(cli->pipe_auth_flags & AUTH_PIPE_SIGN), BOOLSTR(cli->pipe_auth_flags & AUTH_PIPE_SEAL))); if (dp - prs_data_p(rdata) > prs_data_size(rdata)) { DEBUG(0,("rpc_auth_pipe: schannel auth data > data size !\n")); return False; } DEBUG(10,("rpc_auth_pipe: packet:\n")); dump_data(100, dp, auth_len); prs_init(&auth_verf, 0, cli->mem_ctx, UNMARSHALL); /* The endinness must be preserved. JRA. */ prs_set_endian_data( &auth_verf, rdata->bigendian_data); /* Point this new parse struct at the auth section of the main parse struct - rather than copying it. Avoids needing to free it on every error */ prs_give_memory(&auth_verf, dp, RPC_HDR_AUTH_LEN + auth_len, False /* not dynamic */); prs_set_offset(&auth_verf, 0); { int auth_type; int auth_level; if (!smb_io_rpc_hdr_auth("auth_hdr", &rhdr_auth, &auth_verf, 0)) { DEBUG(0, ("rpc_auth_pipe: Could not parse auth header\n")); return False; } /* Let the caller know how much padding at the end of the data */ *pauth_padding_len = rhdr_auth.padding; /* Check it's the type of reply we were expecting to decode */ get_auth_type_level(cli->pipe_auth_flags, &auth_type, &auth_level); if (rhdr_auth.auth_type != auth_type) { DEBUG(0, ("BAD auth type %d (should be %d)\n", rhdr_auth.auth_type, auth_type)); return False; } if (rhdr_auth.auth_level != auth_level) { DEBUG(0, ("BAD auth level %d (should be %d)\n", rhdr_auth.auth_level, auth_level)); return False; } } if (pkt_type == RPC_BINDACK) { if (cli->pipe_auth_flags & AUTH_PIPE_NTLMSSP) { /* copy the next auth_len bytes into a buffer for later use */ DATA_BLOB ntlmssp_verf = data_blob(NULL, auth_len); BOOL store_ok; /* save the reply away, for use a little later */ prs_copy_data_out((char *)ntlmssp_verf.data, &auth_verf, auth_len); store_ok = (NT_STATUS_IS_OK(ntlmssp_store_response(cli->ntlmssp_pipe_state, ntlmssp_verf))); data_blob_free(&ntlmssp_verf); return store_ok; } else if (cli->pipe_auth_flags & AUTH_PIPE_NETSEC) { /* nothing to do here - we don't seem to be able to validate the bindack based on VL's comments */ return True; } } if (cli->pipe_auth_flags & AUTH_PIPE_NTLMSSP) { NTSTATUS nt_status; DATA_BLOB sig; if ((cli->pipe_auth_flags & AUTH_PIPE_SIGN) || (cli->pipe_auth_flags & AUTH_PIPE_SEAL)) { if (auth_len != RPC_AUTH_NTLMSSP_CHK_LEN) { DEBUG(0,("rpc_auth_pipe: wrong ntlmssp auth len %d\n", auth_len)); return False; } sig = data_blob(NULL, auth_len); prs_copy_data_out((char *)sig.data, &auth_verf, auth_len); } /* * Unseal any sealed data in the PDU, not including the * 8 byte auth_header or the auth_data. */ /* * Now unseal and check the auth verifier in the auth_data at * the end of the packet. */ if (cli->pipe_auth_flags & AUTH_PIPE_SEAL) { if (data_len < 0) { DEBUG(1, ("Can't unseal - data_len < 0!!\n")); return False; } nt_status = ntlmssp_unseal_packet(cli->ntlmssp_pipe_state, (unsigned char *)reply_data, data_len, &sig); } else if (cli->pipe_auth_flags & AUTH_PIPE_SIGN) { nt_status = ntlmssp_check_packet(cli->ntlmssp_pipe_state, (const unsigned char *)reply_data, data_len, &sig); } data_blob_free(&sig); if (!NT_STATUS_IS_OK(nt_status)) { DEBUG(0, ("rpc_auth_pipe: could not validate " "incoming NTLMSSP packet!\n")); return False; } } if (cli->pipe_auth_flags & AUTH_PIPE_NETSEC) { RPC_AUTH_NETSEC_CHK chk; if (auth_len != RPC_AUTH_NETSEC_CHK_LEN) { DEBUG(0,("rpc_auth_pipe: wrong schannel auth len %d\n", auth_len)); return False; } if (!smb_io_rpc_auth_netsec_chk("schannel_auth_sign", &chk, &auth_verf, 0)) { DEBUG(0, ("rpc_auth_pipe: schannel unmarshalling " "RPC_AUTH_NETSECK_CHK failed\n")); return False; } if (!netsec_decode(&cli->auth_info, cli->pipe_auth_flags, SENDER_IS_ACCEPTOR, &chk, reply_data, data_len)) { DEBUG(0, ("rpc_auth_pipe: Could not decode schannel\n")); return False; } cli->auth_info.seq_num++; } return True; }
void dump_client_map_error_packet(FILE *file, int fd, unsigned int packet_id, int packet_len) { fprintf(file, "Unknown client packet: 0x%x %u, len: %5d\n", packet_id, packet_id, packet_len); dump_data(file, fd, packet_len); }
void handle_command(struct drpc_packet *pkt, char *buf) { unsigned long pid; unsigned long tid; unsigned long addr; unsigned long len; unsigned long sel; unsigned long flags; unsigned long n; CONTEXT *ctxt; // Validate request if (pkt->startmark != startmark) logmsg("WARNING: unexpected startmark %08X\n", pkt->startmark); if (pkt->reserved1 != 0) logmsg("WARNING: reserved1 is %08X\n", pkt->reserved1); if (pkt->reserved2 != 0) logmsg("WARNING: reserved2 is %08X\n", pkt->reserved2); if (pkt->result != 0) logmsg("WARNING: result is %08X\n", pkt->result); // Execute command switch (pkt->cmd) { case DRPC_GET_SYSTEM_VERSION: logmsg("COMMAND GetSystemVersion: spnamelen=%d, buildnamelen=%d\n", *(unsigned long *) (buf + 0), *(unsigned long *) (buf + 8)); get_system_version(pkt, buf); break; case DRPC_DEBUG_BREAK: tid = *(unsigned long *) (buf + 0); logmsg("COMMAND DebugBreak hthread=%08X\n", tid); pkt->result = E_FAIL; break; case DRPC_GET_HOST_INFO: logmsg("COMMAND GetHostInfo: hostlen=%d, transportlen=%d\n", *(unsigned long *) (buf + 0), *(unsigned long *) (buf + 8)); get_host_info(pkt, buf); break; case DRPC_GET_CPU_INFO: logmsg("COMMAND GetCpuInfo: maxlen=%d\n", *(unsigned long *) buf); get_cpu_info(pkt, buf); break; case DRPC_GET_PROCESS_LIST: logmsg("COMMAND GetProcessList: maxpids=%d\n", *(unsigned long *) buf); get_process_list(pkt, buf); break; case DRPC_GET_PROCESS_NAME: pid = *(unsigned long *) buf; logmsg("COMMAND GetProcessName pid=%d:\n", pid); get_process_name(pkt, buf); break; case DRPC_DEBUG_PROCESS: pid = *(unsigned long *) buf; logmsg("COMMAND DebugProcess pid=%d (%08X):\n", pid, pid); pkt->result = E_FAIL; break; case DRPC_OPEN_PROCESS: pid = *(unsigned long *) buf; flags = *(unsigned long *) (buf + 8); logmsg("COMMAND OpenProcess pid=%d (%08X) flags=%08X:\n", pid, pid, flags); open_process(pkt, buf); break; case DRPC_CREATE_PROCESS: pid = *(unsigned long *) buf; logmsg("COMMAND CreateProcess: cmd=%S flags=%08X:\n", buf, *(unsigned long *)(buf + pkt->reqlen - 4)); pkt->result = E_FAIL; break; case DRPC_READ_PROCESS_MEMORY: pid = *(unsigned long *) (buf + 0); addr = *(unsigned long *) (buf + 8); len = *(unsigned long *) (buf + 16); logmsg("COMMAND ReadProcessMemory hproc=%08X addr=%08x len=%d:\n", pid, addr, len); read_memory(pkt, buf); break; case DRPC_WRITE_PROCESS_MEMORY: pid = *(unsigned long *) (buf + 0); addr = *(unsigned long *) (buf + 8); len = *(unsigned long *) (buf + 16); logmsg("COMMAND WriteProcessMemory hproc=%08X addr=%08x len=%d:\n", pid, addr, len); write_memory(pkt, buf); break; case DRPC_SUSPEND_THREAD: len = *(unsigned long *) (buf + 0); logmsg("COMMAND SuspendThread: hthread="); for (n = 0; n < len; n++) { tid = *(unsigned long *) (buf + 8 + n * 8); logmsg(" %08X", tid); } logmsg("\n"); suspend_threads(pkt, buf); break; case DRPC_RESUME_THREAD: len = *(unsigned long *) (buf + 0); logmsg("COMMAND ResumeThread: hthread="); for (n = 0; n < len; n++) { tid = *(unsigned long *) (buf + 8 + n * 8); logmsg(" %08X", tid); } logmsg("\n"); resume_threads(pkt, buf); break; case DRPC_GET_THREAD_CONTEXT: tid = *(unsigned long *) (buf + 0); flags = *(unsigned long *) (buf + 8); len = *(unsigned long *) (buf + 16); logmsg("COMMAND GetThreadContext hthread=%08X context=%08x len=%d:\n", tid, flags, len); get_context(pkt, buf); break; case DRPC_SET_THREAD_CONTEXT: tid = *(unsigned long *) (buf + 0); len = *(unsigned long *) (buf + 8); ctxt = (CONTEXT *) (buf + 12); logmsg("COMMAND SetThreadContext hthread=%08X eax=%08x len=%d:\n", tid, ctxt->Eax, len); set_context(pkt, buf); break; case DRPC_GET_PEB_ADDRESS: pid = *(unsigned long *) (buf + 0); logmsg("COMMAND GetPebAddress hproc=%08X:\n", pid); get_peb_address(pkt, buf); break; case DRPC_GET_THREAD_SELECTOR: tid = *(unsigned long *) (buf + 0); sel = *(unsigned long *) (buf + 8); len = *(unsigned long *) (buf + 12); logmsg("COMMAND GetThreadSelector hthread=%08X selector=%08x len=%08x:\n", tid, sel, len); get_thread_selector(pkt, buf); break; case DRPC_GET_DEBUG_EVENT: logmsg("COMMAND GetDebugEvent %08X %08X:\n", *(unsigned long *) buf, *(unsigned long *) (buf + 4)); get_debug_event(pkt, buf); break; case DRPC_CONTINUE_DEBUG_EVENT: flags = *(unsigned long *) buf; if (flags == 0x00010001) logmsg("COMMAND ContinueDebugEvent: DBG_EXCEPTION_HANDLED\n"); else if (flags == 0x00010002) logmsg("COMMAND ContinueDebugEvent: DBG_CONTINUE\n"); else logmsg("COMMAND ContinueDebugEvent: %08X\n", flags); break; case 0x0000C001: logmsg("COMMAND 0000C001\n"); pkt->result = dbg_state; break; case 0x0004C002: logmsg("COMMAND 0004C002\n"); *(unsigned long *) buf = 5; break; default: logmsg("COMMAND %08X ??? (reqlen=%d, rsplen=%d):\n", pkt->cmd, pkt->reqlen, pkt->rsplen); if (pkt->reqlen > 0) { logmsg("reqdata: "); dump_data(stdout, buf, pkt->reqlen > 256 ? 256 : pkt->reqlen, 4, NULL); if (logfile) dump_data(logfile, buf, pkt->reqlen, 4, NULL); } pkt->result = E_FAIL; } pkt->cmd |= 0x00010000; }
NTSTATUS gensec_ntlmssp_server_negotiate(struct gensec_security *gensec_security, TALLOC_CTX *out_mem_ctx, const DATA_BLOB request, DATA_BLOB *reply) { struct gensec_ntlmssp_context *gensec_ntlmssp = talloc_get_type_abort(gensec_security->private_data, struct gensec_ntlmssp_context); struct ntlmssp_state *ntlmssp_state = gensec_ntlmssp->ntlmssp_state; struct auth4_context *auth_context = gensec_security->auth_context; DATA_BLOB struct_blob; uint32_t neg_flags = 0; uint32_t ntlmssp_command, chal_flags; uint8_t cryptkey[8]; const char *target_name; NTSTATUS status; struct timeval tv_now = timeval_current(); /* * See [MS-NLMP] * * Windows NT 4.0, windows_2000: use 30 minutes, * Windows XP, Windows Server 2003, Windows Vista, * Windows Server 2008, Windows 7, and Windows Server 2008 R2 * use 36 hours. * * Newer systems doesn't check this, likely because the * connectionless NTLMSSP is no longer supported. * * As we expect the AUTHENTICATION_MESSAGE to arrive * directly after the NEGOTIATE_MESSAGE (typically less than * as 1 second later). We use a hard timeout of 30 Minutes. * * We don't look at AUTHENTICATE_MESSAGE.NtChallengeResponse.TimeStamp * instead we just remember our own time. */ uint32_t max_lifetime = 30 * 60; struct timeval tv_end = timeval_add(&tv_now, max_lifetime, 0); /* parse the NTLMSSP packet */ #if 0 file_save("ntlmssp_negotiate.dat", request.data, request.length); #endif if (request.length) { if (request.length > UINT16_MAX) { DEBUG(1, ("ntlmssp_server_negotiate: reject large request of length %u\n", (unsigned int)request.length)); return NT_STATUS_INVALID_PARAMETER; } if ((request.length < 16) || !msrpc_parse(ntlmssp_state, &request, "Cdd", "NTLMSSP", &ntlmssp_command, &neg_flags)) { DEBUG(1, ("ntlmssp_server_negotiate: failed to parse NTLMSSP Negotiate of length %u\n", (unsigned int)request.length)); dump_data(2, request.data, request.length); return NT_STATUS_INVALID_PARAMETER; } debug_ntlmssp_flags(neg_flags); if (DEBUGLEVEL >= 10) { struct NEGOTIATE_MESSAGE *negotiate = talloc( ntlmssp_state, struct NEGOTIATE_MESSAGE); if (negotiate != NULL) { status = ntlmssp_pull_NEGOTIATE_MESSAGE( &request, negotiate, negotiate); if (NT_STATUS_IS_OK(status)) { NDR_PRINT_DEBUG(NEGOTIATE_MESSAGE, negotiate); } TALLOC_FREE(negotiate); } } } status = ntlmssp_handle_neg_flags(ntlmssp_state, neg_flags, "negotiate"); if (!NT_STATUS_IS_OK(status)){ return status; } /* Ask our caller what challenge they would like in the packet */ if (auth_context->get_ntlm_challenge) { status = auth_context->get_ntlm_challenge(auth_context, cryptkey); if (!NT_STATUS_IS_OK(status)) { DEBUG(1, ("gensec_ntlmssp_server_negotiate: failed to get challenge: %s\n", nt_errstr(status))); return status; } } else { DEBUG(1, ("gensec_ntlmssp_server_negotiate: backend doesn't give a challenge\n")); return NT_STATUS_NOT_IMPLEMENTED; } /* The flags we send back are not just the negotiated flags, * they are also 'what is in this packet'. Therfore, we * operate on 'chal_flags' from here on */ chal_flags = ntlmssp_state->neg_flags; ntlmssp_state->server.challenge_endtime = timeval_to_nttime(&tv_end); /* get the right name to fill in as 'target' */ target_name = ntlmssp_target_name(ntlmssp_state, neg_flags, &chal_flags); if (target_name == NULL) return NT_STATUS_INVALID_PARAMETER; ntlmssp_state->chal = data_blob_talloc(ntlmssp_state, cryptkey, 8); ntlmssp_state->internal_chal = data_blob_talloc(ntlmssp_state, cryptkey, 8); /* This creates the 'blob' of names that appears at the end of the packet */ if (chal_flags & NTLMSSP_NEGOTIATE_TARGET_INFO) { enum ndr_err_code err; struct AV_PAIR *pairs = NULL; uint32_t count = 5; pairs = talloc_zero_array(ntlmssp_state, struct AV_PAIR, count + 1); if (pairs == NULL) { return NT_STATUS_NO_MEMORY; } pairs[0].AvId = MsvAvNbDomainName; pairs[0].Value.AvNbDomainName = target_name; pairs[1].AvId = MsvAvNbComputerName; pairs[1].Value.AvNbComputerName = ntlmssp_state->server.netbios_name; pairs[2].AvId = MsvAvDnsDomainName; pairs[2].Value.AvDnsDomainName = ntlmssp_state->server.dns_domain; pairs[3].AvId = MsvAvDnsComputerName; pairs[3].Value.AvDnsComputerName= ntlmssp_state->server.dns_name; if (!ntlmssp_state->force_old_spnego) { pairs[4].AvId = MsvAvTimestamp; pairs[4].Value.AvTimestamp = timeval_to_nttime(&tv_now); count += 1; pairs[5].AvId = MsvAvEOL; } else { pairs[4].AvId = MsvAvEOL; } ntlmssp_state->server.av_pair_list.count = count; ntlmssp_state->server.av_pair_list.pair = pairs; err = ndr_push_struct_blob(&struct_blob, ntlmssp_state, &ntlmssp_state->server.av_pair_list, (ndr_push_flags_fn_t)ndr_push_AV_PAIR_LIST); if (!NDR_ERR_CODE_IS_SUCCESS(err)) { return NT_STATUS_NO_MEMORY; } } else {
NTSTATUS ntlmssp_client_challenge(struct gensec_security *gensec_security, TALLOC_CTX *out_mem_ctx, const DATA_BLOB in, DATA_BLOB *out) { struct gensec_ntlmssp_context *gensec_ntlmssp = talloc_get_type_abort(gensec_security->private_data, struct gensec_ntlmssp_context); struct ntlmssp_state *ntlmssp_state = gensec_ntlmssp->ntlmssp_state; uint32_t chal_flags, ntlmssp_command, unkn1, unkn2; DATA_BLOB server_domain_blob; DATA_BLOB challenge_blob; DATA_BLOB target_info = data_blob(NULL, 0); char *server_domain; const char *chal_parse_string; const char *auth_gen_string; DATA_BLOB lm_response = data_blob(NULL, 0); DATA_BLOB nt_response = data_blob(NULL, 0); DATA_BLOB session_key = data_blob(NULL, 0); DATA_BLOB lm_session_key = data_blob(NULL, 0); DATA_BLOB encrypted_session_key = data_blob(NULL, 0); NTSTATUS nt_status; int flags = 0; const char *user, *domain; TALLOC_CTX *mem_ctx = talloc_new(out_mem_ctx); if (!mem_ctx) { return NT_STATUS_NO_MEMORY; } if (!msrpc_parse(mem_ctx, &in, "CdBd", "NTLMSSP", &ntlmssp_command, &server_domain_blob, &chal_flags)) { DEBUG(1, ("Failed to parse the NTLMSSP Challenge: (#1)\n")); dump_data(2, in.data, in.length); talloc_free(mem_ctx); return NT_STATUS_INVALID_PARAMETER; } data_blob_free(&server_domain_blob); DEBUG(3, ("Got challenge flags:\n")); debug_ntlmssp_flags(chal_flags); ntlmssp_handle_neg_flags(ntlmssp_state, chal_flags, ntlmssp_state->allow_lm_key); if (ntlmssp_state->unicode) { if (chal_flags & NTLMSSP_NEGOTIATE_TARGET_INFO) { chal_parse_string = "CdUdbddB"; } else { chal_parse_string = "CdUdbdd"; } auth_gen_string = "CdBBUUUBd"; } else { if (chal_flags & NTLMSSP_NEGOTIATE_TARGET_INFO) { chal_parse_string = "CdAdbddB"; } else { chal_parse_string = "CdAdbdd"; } auth_gen_string = "CdBBAAABd"; } if (!msrpc_parse(mem_ctx, &in, chal_parse_string, "NTLMSSP", &ntlmssp_command, &server_domain, &chal_flags, &challenge_blob, 8, &unkn1, &unkn2, &target_info)) { DEBUG(1, ("Failed to parse the NTLMSSP Challenge: (#2)\n")); dump_data(2, in.data, in.length); talloc_free(mem_ctx); return NT_STATUS_INVALID_PARAMETER; } if (chal_flags & NTLMSSP_TARGET_TYPE_SERVER) { ntlmssp_state->server.is_standalone = true; } else { ntlmssp_state->server.is_standalone = false; } /* TODO: parse struct_blob and fill in the rest */ ntlmssp_state->server.netbios_name = ""; ntlmssp_state->server.netbios_domain = server_domain; ntlmssp_state->server.dns_name = ""; ntlmssp_state->server.dns_domain = ""; if (challenge_blob.length != 8) { talloc_free(mem_ctx); return NT_STATUS_INVALID_PARAMETER; } cli_credentials_get_ntlm_username_domain(gensec_security->credentials, mem_ctx, &user, &domain); if (ntlmssp_state->neg_flags & NTLMSSP_NEGOTIATE_NTLM2) { flags |= CLI_CRED_NTLM2; } if (ntlmssp_state->use_ntlmv2) { flags |= CLI_CRED_NTLMv2_AUTH; } if (ntlmssp_state->use_nt_response) { flags |= CLI_CRED_NTLM_AUTH; } if (lpcfg_client_lanman_auth(gensec_security->settings->lp_ctx)) { flags |= CLI_CRED_LANMAN_AUTH; } nt_status = cli_credentials_get_ntlm_response(gensec_security->credentials, mem_ctx, &flags, challenge_blob, target_info, &lm_response, &nt_response, &lm_session_key, &session_key); if (!NT_STATUS_IS_OK(nt_status)) { return nt_status; } if (!(flags & CLI_CRED_LANMAN_AUTH)) { /* LM Key is still possible, just silly, so we do not * allow it. Fortunetly all LM crypto is off by * default and we require command line options to end * up here */ ntlmssp_state->neg_flags &= ~NTLMSSP_NEGOTIATE_LM_KEY; } if (!(flags & CLI_CRED_NTLM2)) { /* NTLM2 is incompatible... */ ntlmssp_state->neg_flags &= ~NTLMSSP_NEGOTIATE_NTLM2; } if ((ntlmssp_state->neg_flags & NTLMSSP_NEGOTIATE_LM_KEY) && lpcfg_client_lanman_auth(gensec_security->settings->lp_ctx) && lm_session_key.length == 16) { DATA_BLOB new_session_key = data_blob_talloc(mem_ctx, NULL, 16); if (lm_response.length == 24) { SMBsesskeygen_lm_sess_key(lm_session_key.data, lm_response.data, new_session_key.data); } else { static const uint8_t zeros[24]; SMBsesskeygen_lm_sess_key(lm_session_key.data, zeros, new_session_key.data); } session_key = new_session_key; dump_data_pw("LM session key\n", session_key.data, session_key.length); } /* Key exchange encryptes a new client-generated session key with the password-derived key */ if (ntlmssp_state->neg_flags & NTLMSSP_NEGOTIATE_KEY_EXCH) { /* Make up a new session key */ uint8_t client_session_key[16]; generate_secret_buffer(client_session_key, sizeof(client_session_key)); /* Encrypt the new session key with the old one */ encrypted_session_key = data_blob_talloc(ntlmssp_state, client_session_key, sizeof(client_session_key)); dump_data_pw("KEY_EXCH session key:\n", encrypted_session_key.data, encrypted_session_key.length); arcfour_crypt(encrypted_session_key.data, session_key.data, encrypted_session_key.length); dump_data_pw("KEY_EXCH session key (enc):\n", encrypted_session_key.data, encrypted_session_key.length); /* Mark the new session key as the 'real' session key */ session_key = data_blob_talloc(mem_ctx, client_session_key, sizeof(client_session_key)); } DEBUG(3, ("NTLMSSP: Set final flags:\n")); debug_ntlmssp_flags(ntlmssp_state->neg_flags); /* this generates the actual auth packet */ nt_status = msrpc_gen(mem_ctx, out, auth_gen_string, "NTLMSSP", NTLMSSP_AUTH, lm_response.data, lm_response.length, nt_response.data, nt_response.length, domain, user, cli_credentials_get_workstation(gensec_security->credentials), encrypted_session_key.data, encrypted_session_key.length, ntlmssp_state->neg_flags); if (!NT_STATUS_IS_OK(nt_status)) { talloc_free(mem_ctx); return nt_status; } ntlmssp_state->session_key = session_key; talloc_steal(ntlmssp_state, session_key.data); talloc_steal(out_mem_ctx, out->data); ntlmssp_state->expected_state = NTLMSSP_DONE; if (gensec_security->want_features & (GENSEC_FEATURE_SIGN|GENSEC_FEATURE_SEAL)) { nt_status = ntlmssp_sign_init(ntlmssp_state); if (!NT_STATUS_IS_OK(nt_status)) { DEBUG(1, ("Could not setup NTLMSSP signing/sealing system (error was: %s)\n", nt_errstr(nt_status))); talloc_free(mem_ctx); return nt_status; } } talloc_free(mem_ctx); return NT_STATUS_OK; }
static BOOL test_ntlm_in_both(void) { BOOL pass = True; NTSTATUS nt_status; uint32 flags = 0; DATA_BLOB nt_response = data_blob(NULL, 24); DATA_BLOB session_key = data_blob(NULL, 16); char lm_key[8]; char lm_hash[16]; char user_session_key[16]; char nt_hash[16]; DATA_BLOB chall = get_challenge(); char *error_string; ZERO_STRUCT(lm_key); ZERO_STRUCT(user_session_key); flags |= WBFLAG_PAM_LMKEY; flags |= WBFLAG_PAM_USER_SESSION_KEY; SMBNTencrypt(opt_password,chall.data,nt_response.data); E_md4hash(opt_password, (unsigned char *)nt_hash); SMBsesskeygen_ntv1((const unsigned char *)nt_hash, NULL, session_key.data); E_deshash(opt_password, (unsigned char *)lm_hash); nt_status = contact_winbind_auth_crap(opt_username, opt_domain, opt_workstation, &chall, &nt_response, &nt_response, flags, (unsigned char *)lm_key, (unsigned char *)user_session_key, &error_string, NULL); data_blob_free(&nt_response); if (!NT_STATUS_IS_OK(nt_status)) { d_printf("%s (0x%x)\n", error_string, NT_STATUS_V(nt_status)); SAFE_FREE(error_string); return False; } if (memcmp(lm_hash, lm_key, sizeof(lm_key)) != 0) { DEBUG(1, ("LM Key does not match expectations!\n")); DEBUG(1, ("lm_key:\n")); dump_data(1, lm_key, 8); DEBUG(1, ("expected:\n")); dump_data(1, lm_hash, 8); pass = False; } if (memcmp(session_key.data, user_session_key, sizeof(user_session_key)) != 0) { DEBUG(1, ("NT Session Key does not match expectations!\n")); DEBUG(1, ("user_session_key:\n")); dump_data(1, user_session_key, 16); DEBUG(1, ("expected:\n")); dump_data(1, (const char *)session_key.data, session_key.length); pass = False; } return pass; }
static BOOL test_lmv2_ntlmv2_broken(enum ntlm_break break_which) { BOOL pass = True; NTSTATUS nt_status; uint32 flags = 0; DATA_BLOB ntlmv2_response = data_blob(NULL, 0); DATA_BLOB lmv2_response = data_blob(NULL, 0); DATA_BLOB ntlmv2_session_key = data_blob(NULL, 0); DATA_BLOB names_blob = NTLMv2_generate_names_blob(get_winbind_netbios_name(), get_winbind_domain()); uchar user_session_key[16]; DATA_BLOB chall = get_challenge(); char *error_string; ZERO_STRUCT(user_session_key); flags |= WBFLAG_PAM_USER_SESSION_KEY; if (!SMBNTLMv2encrypt(opt_username, opt_domain, opt_password, &chall, &names_blob, &lmv2_response, &ntlmv2_response, &ntlmv2_session_key)) { data_blob_free(&names_blob); return False; } data_blob_free(&names_blob); switch (break_which) { case BREAK_NONE: break; case BREAK_LM: lmv2_response.data[0]++; break; case BREAK_NT: ntlmv2_response.data[0]++; break; case NO_LM: data_blob_free(&lmv2_response); break; case NO_NT: data_blob_free(&ntlmv2_response); break; } nt_status = contact_winbind_auth_crap(opt_username, opt_domain, opt_workstation, &chall, &lmv2_response, &ntlmv2_response, flags, NULL, user_session_key, &error_string, NULL); data_blob_free(&lmv2_response); data_blob_free(&ntlmv2_response); if (!NT_STATUS_IS_OK(nt_status)) { d_printf("%s (0x%x)\n", error_string, NT_STATUS_V(nt_status)); SAFE_FREE(error_string); return break_which == BREAK_NT; } if (break_which != NO_NT && break_which != BREAK_NT && memcmp(ntlmv2_session_key.data, user_session_key, sizeof(user_session_key)) != 0) { DEBUG(1, ("USER (NTLMv2) Session Key does not match expectations!\n")); DEBUG(1, ("user_session_key:\n")); dump_data(1, (const char *)user_session_key, 16); DEBUG(1, ("expected:\n")); dump_data(1, (const char *)ntlmv2_session_key.data, ntlmv2_session_key.length); pass = False; } return pass; }
static bool smb_pwd_check_ntlmv2(TALLOC_CTX *mem_ctx, const DATA_BLOB *ntv2_response, const uint8_t *part_passwd, const DATA_BLOB *sec_blob, const char *user, const char *domain, bool upper_case_domain, /* should the domain be transformed into upper case? */ DATA_BLOB *user_sess_key) { /* Finish the encryption of part_passwd. */ uint8_t kr[16]; uint8_t value_from_encryption[16]; DATA_BLOB client_key_data; if (part_passwd == NULL) { DEBUG(10,("No password set - DISALLOWING access\n")); /* No password set - always false */ return false; } if (sec_blob->length != 8) { DEBUG(0, ("smb_pwd_check_ntlmv2: incorrect challenge size (%lu)\n", (unsigned long)sec_blob->length)); return false; } if (ntv2_response->length < 24) { /* We MUST have more than 16 bytes, or the stuff below will go crazy. No known implementation sends less than the 24 bytes for LMv2, let alone NTLMv2. */ DEBUG(0, ("smb_pwd_check_ntlmv2: incorrect password length (%lu)\n", (unsigned long)ntv2_response->length)); return false; } client_key_data = data_blob_talloc(mem_ctx, ntv2_response->data+16, ntv2_response->length-16); /* todo: should we be checking this for anything? We can't for LMv2, but for NTLMv2 it is meant to contain the current time etc. */ if (!ntv2_owf_gen(part_passwd, user, domain, upper_case_domain, kr)) { return false; } SMBOWFencrypt_ntv2(kr, sec_blob, &client_key_data, value_from_encryption); #if DEBUG_PASSWORD DEBUG(100,("Part password (P16) was |\n")); dump_data(100, part_passwd, 16); DEBUGADD(100,("Password from client was |\n")); dump_data(100, ntv2_response->data, ntv2_response->length); DEBUGADD(100,("Variable data from client was |\n")); dump_data(100, client_key_data.data, client_key_data.length); DEBUGADD(100,("Given challenge was |\n")); dump_data(100, sec_blob->data, sec_blob->length); DEBUGADD(100,("Value from encryption was |\n")); dump_data(100, value_from_encryption, 16); #endif data_blob_clear_free(&client_key_data); if (memcmp(value_from_encryption, ntv2_response->data, 16) == 0) { if (user_sess_key != NULL) { *user_sess_key = data_blob_talloc(mem_ctx, NULL, 16); SMBsesskeygen_ntv2(kr, value_from_encryption, user_sess_key->data); } return true; } return false; }
virtual boost::filesystem::fstream& dumpDataToFile(boost::filesystem::fstream& os) const { os << makeTimeLabel() << " "; std::ostringstream oss; dump_data(oss); os << oss.str(); return os; }
static BOOL api_pipe_ntlmssp_verify(pipes_struct *p, RPC_AUTH_NTLMSSP_RESP *ntlmssp_resp) { uchar lm_owf[24]; uchar nt_owf[128]; int nt_pw_len; int lm_pw_len; fstring user_name; fstring domain; fstring wks; NTSTATUS nt_status; struct auth_context *auth_context = NULL; auth_usersupplied_info *user_info = NULL; auth_serversupplied_info *server_info = NULL; DEBUG(5,("api_pipe_ntlmssp_verify: checking user details\n")); memset(p->user_name, '\0', sizeof(p->user_name)); memset(p->pipe_user_name, '\0', sizeof(p->pipe_user_name)); memset(p->domain, '\0', sizeof(p->domain)); memset(p->wks, '\0', sizeof(p->wks)); /* Set up for non-authenticated user. */ delete_nt_token(&p->pipe_user.nt_user_token); p->pipe_user.ngroups = 0; SAFE_FREE( p->pipe_user.groups); /* * Setup an empty password for a guest user. */ /* * We always negotiate UNICODE. */ if (p->ntlmssp_chal_flags & NTLMSSP_NEGOTIATE_UNICODE) { rpcstr_pull(user_name, ntlmssp_resp->user, sizeof(fstring), ntlmssp_resp->hdr_usr.str_str_len*2, 0 ); rpcstr_pull(domain, ntlmssp_resp->domain, sizeof(fstring), ntlmssp_resp->hdr_domain.str_str_len*2, 0); rpcstr_pull(wks, ntlmssp_resp->wks, sizeof(fstring), ntlmssp_resp->hdr_wks.str_str_len*2, 0); } else { pull_ascii_fstring(user_name, ntlmssp_resp->user); pull_ascii_fstring(domain, ntlmssp_resp->domain); pull_ascii_fstring(wks, ntlmssp_resp->wks); } DEBUG(5,("user: %s domain: %s wks: %s\n", user_name, domain, wks)); nt_pw_len = MIN(sizeof(nt_owf), ntlmssp_resp->hdr_nt_resp.str_str_len); lm_pw_len = MIN(sizeof(lm_owf), ntlmssp_resp->hdr_lm_resp.str_str_len); memcpy(lm_owf, ntlmssp_resp->lm_resp, sizeof(lm_owf)); memcpy(nt_owf, ntlmssp_resp->nt_resp, nt_pw_len); #ifdef DEBUG_PASSWORD DEBUG(100,("lm, nt owfs, chal\n")); dump_data(100, (char *)lm_owf, sizeof(lm_owf)); dump_data(100, (char *)nt_owf, nt_pw_len); dump_data(100, (char *)p->challenge, 8); #endif /* * Allow guest access. Patch from Shirish Kalele <*****@*****.**>. */ if (*user_name) { /* * Do the length checking only if user is not NULL. */ if (ntlmssp_resp->hdr_lm_resp.str_str_len == 0) return False; if (ntlmssp_resp->hdr_nt_resp.str_str_len == 0) return False; if (ntlmssp_resp->hdr_usr.str_str_len == 0) return False; if (ntlmssp_resp->hdr_domain.str_str_len == 0) return False; if (ntlmssp_resp->hdr_wks.str_str_len == 0) return False; } make_auth_context_fixed(&auth_context, (uchar*)p->challenge); if (!make_user_info_netlogon_network(&user_info, user_name, domain, wks, lm_owf, lm_pw_len, nt_owf, nt_pw_len)) { DEBUG(0,("make_user_info_netlogon_network failed! Failing authenticaion.\n")); return False; } nt_status = auth_context->check_ntlm_password(auth_context, user_info, &server_info); (auth_context->free)(&auth_context); free_user_info(&user_info); p->ntlmssp_auth_validated = NT_STATUS_IS_OK(nt_status); if (!p->ntlmssp_auth_validated) { DEBUG(1,("api_pipe_ntlmssp_verify: User [%s]\\[%s] from machine %s \ failed authentication on named pipe %s.\n", domain, user_name, wks, p->name )); free_server_info(&server_info); return False; }
bool make_user_info_for_reply(struct auth_usersupplied_info **user_info, const char *smb_name, const char *client_domain, const struct tsocket_address *remote_address, const uint8 chal[8], DATA_BLOB plaintext_password) { DATA_BLOB local_lm_blob; DATA_BLOB local_nt_blob; NTSTATUS ret = NT_STATUS_UNSUCCESSFUL; char *plaintext_password_string; /* * Not encrypted - do so. */ DEBUG(5,("make_user_info_for_reply: User passwords not in encrypted " "format.\n")); if (plaintext_password.data && plaintext_password.length) { unsigned char local_lm_response[24]; #ifdef DEBUG_PASSWORD DEBUG(10,("Unencrypted password (len %d):\n", (int)plaintext_password.length)); dump_data(100, plaintext_password.data, plaintext_password.length); #endif SMBencrypt( (const char *)plaintext_password.data, (const uchar*)chal, local_lm_response); local_lm_blob = data_blob(local_lm_response, 24); /* We can't do an NT hash here, as the password needs to be case insensitive */ local_nt_blob = data_blob_null; } else { local_lm_blob = data_blob_null; local_nt_blob = data_blob_null; } plaintext_password_string = talloc_strndup(talloc_tos(), (const char *)plaintext_password.data, plaintext_password.length); if (!plaintext_password_string) { return false; } ret = make_user_info( user_info, smb_name, smb_name, client_domain, client_domain, get_remote_machine_name(), remote_address, local_lm_blob.data ? &local_lm_blob : NULL, local_nt_blob.data ? &local_nt_blob : NULL, NULL, NULL, plaintext_password_string, AUTH_PASSWORD_PLAIN); if (plaintext_password_string) { memset(plaintext_password_string, '\0', strlen(plaintext_password_string)); talloc_free(plaintext_password_string); } data_blob_free(&local_lm_blob); return NT_STATUS_IS_OK(ret) ? true : false; }
NTSTATUS gensec_ntlmssp_server_negotiate(struct gensec_security *gensec_security, TALLOC_CTX *out_mem_ctx, const DATA_BLOB request, DATA_BLOB *reply) { struct gensec_ntlmssp_context *gensec_ntlmssp = talloc_get_type_abort(gensec_security->private_data, struct gensec_ntlmssp_context); struct ntlmssp_state *ntlmssp_state = gensec_ntlmssp->ntlmssp_state; struct auth4_context *auth_context = gensec_security->auth_context; DATA_BLOB struct_blob; uint32_t neg_flags = 0; uint32_t ntlmssp_command, chal_flags; uint8_t cryptkey[8]; const char *target_name; NTSTATUS status; /* parse the NTLMSSP packet */ #if 0 file_save("ntlmssp_negotiate.dat", request.data, request.length); #endif if (request.length) { if ((request.length < 16) || !msrpc_parse(ntlmssp_state, &request, "Cdd", "NTLMSSP", &ntlmssp_command, &neg_flags)) { DEBUG(1, ("ntlmssp_server_negotiate: failed to parse NTLMSSP Negotiate of length %u\n", (unsigned int)request.length)); dump_data(2, request.data, request.length); return NT_STATUS_INVALID_PARAMETER; } debug_ntlmssp_flags(neg_flags); if (DEBUGLEVEL >= 10) { struct NEGOTIATE_MESSAGE *negotiate = talloc( ntlmssp_state, struct NEGOTIATE_MESSAGE); if (negotiate != NULL) { status = ntlmssp_pull_NEGOTIATE_MESSAGE( &request, negotiate, negotiate); if (NT_STATUS_IS_OK(status)) { NDR_PRINT_DEBUG(NEGOTIATE_MESSAGE, negotiate); } TALLOC_FREE(negotiate); } } } ntlmssp_handle_neg_flags(ntlmssp_state, neg_flags, ntlmssp_state->allow_lm_key); /* Ask our caller what challenge they would like in the packet */ if (auth_context->get_ntlm_challenge) { status = auth_context->get_ntlm_challenge(auth_context, cryptkey); if (!NT_STATUS_IS_OK(status)) { DEBUG(1, ("gensec_ntlmssp_server_negotiate: failed to get challenge: %s\n", nt_errstr(status))); return status; } } else { DEBUG(1, ("gensec_ntlmssp_server_negotiate: backend doesn't give a challenge\n")); return NT_STATUS_NOT_IMPLEMENTED; } /* The flags we send back are not just the negotiated flags, * they are also 'what is in this packet'. Therfore, we * operate on 'chal_flags' from here on */ chal_flags = ntlmssp_state->neg_flags; /* get the right name to fill in as 'target' */ target_name = ntlmssp_target_name(ntlmssp_state, neg_flags, &chal_flags); if (target_name == NULL) return NT_STATUS_INVALID_PARAMETER; ntlmssp_state->chal = data_blob_talloc(ntlmssp_state, cryptkey, 8); ntlmssp_state->internal_chal = data_blob_talloc(ntlmssp_state, cryptkey, 8); /* This creates the 'blob' of names that appears at the end of the packet */ if (chal_flags & NTLMSSP_NEGOTIATE_TARGET_INFO) { enum ndr_err_code err; struct AV_PAIR *pairs = NULL; uint32_t count = 5; pairs = talloc_zero_array(ntlmssp_state, struct AV_PAIR, count); if (pairs == NULL) { return NT_STATUS_NO_MEMORY; } pairs[0].AvId = MsvAvNbDomainName; pairs[0].Value.AvNbDomainName = target_name; pairs[1].AvId = MsvAvNbComputerName; pairs[1].Value.AvNbComputerName = ntlmssp_state->server.netbios_name; pairs[2].AvId = MsvAvDnsDomainName; pairs[2].Value.AvDnsDomainName = ntlmssp_state->server.dns_domain; pairs[3].AvId = MsvAvDnsComputerName; pairs[3].Value.AvDnsComputerName= ntlmssp_state->server.dns_name; pairs[4].AvId = MsvAvEOL; ntlmssp_state->server.av_pair_list.count = count; ntlmssp_state->server.av_pair_list.pair = pairs; err = ndr_push_struct_blob(&struct_blob, ntlmssp_state, &ntlmssp_state->server.av_pair_list, (ndr_push_flags_fn_t)ndr_push_AV_PAIR_LIST); if (!NDR_ERR_CODE_IS_SUCCESS(err)) { return NT_STATUS_NO_MEMORY; } } else {
int ftp_transfer(UrlResource *rsrc) { Url *u = NULL; char *line = NULL; int sock = 0; int data_sock = 0; int passive = 1; int retval = 0; u = rsrc->url; /* * first of all, if this is proxied, just pass it off to the * http module, since that's how we support proxying. */ rsrc->proxy = get_proxy("FTP_PROXY"); if (rsrc->proxy && (rsrc->proxy[0] != '\0')) { return http_transfer(rsrc); } ftp_set_defaults(rsrc, u); if (!(sock = tcp_connect(rsrc->op, u->host, u->port))) return FALSE; if (!(line = get_line(rsrc, sock))) return FALSE; if (!check_numeric("220", line)) { ui_error(rsrc->op, "bad ftp server greeting: %s", line); nvfree(line); return FALSE; } send_control(sock, "USER ", u->username, "\r\n", NULL); if (!(line = get_line(rsrc, sock))) return FALSE; /* do the password dance */ if (!check_numeric("230", line)) { if (!check_numeric("331", line)) { ui_error(rsrc->op, "bad/unexpected response: %s", line); nvfree(line); return FALSE; } else { nvfree(line); send_control(sock, "PASS ", u->password, "\r\n", NULL); if (!((line = get_line(rsrc, sock)) && check_numeric("230", line)) ) { nvfree(line); ui_error(rsrc->op, "login failed"); return FALSE; } nvfree(line); } } /* set binmode */ send_control(sock, "TYPE I\r\n", NULL); if (!(line = get_line(rsrc, sock))) return 0; nvfree(line); if (u->path) { send_control(sock, "CWD ", u->path, "\r\n", NULL); if (!((line = get_line(rsrc, sock)) && check_numeric("250", line))) { nvfree(line); close_quit(sock); return 0; } nvfree(line); } /* finally, the good stuff */ /* get a socket for reading. try passive first. */ if ((data_sock = get_passive_sock(rsrc, sock)) == -1) { return FALSE; } if (!data_sock) { if ((data_sock = get_sock(rsrc, sock)) < 1) return 0; else passive = 0; } if (u->file) { send_control(sock, "SIZE ", u->file, "\r\n", NULL); line = get_line(rsrc, sock); if (line && check_numeric("213", line)) { rsrc->outfile_size = atoi(line + 3); } else { rsrc->outfile_size = 0; } } if (u->file) send_control(sock, "RETR ", u->file, "\r\n", NULL); else send_control(sock, "NLST\r\n", NULL); if (!((line = get_line(rsrc, sock)) && (check_numeric("150", line) || check_numeric("125", line)))) { nvfree(line); close_quit(sock); return 0; } if (!passive) data_sock = accept(data_sock, NULL, NULL); nvfree(line); retval = dump_data(rsrc, data_sock); line = get_line(rsrc, sock); /* 226 Transfer complete */ nvfree(line); send_control(sock, "QUIT\r\n", NULL); line = get_line(rsrc, sock); /* 221 Goodbye */ nvfree(line); close(sock); close(data_sock); return retval; } /* ftp_transfer() */
static BOOL test_lm_ntlm_broken(enum ntlm_break break_which) { BOOL pass = True; NTSTATUS nt_status; uint32 flags = 0; DATA_BLOB lm_response = data_blob(NULL, 24); DATA_BLOB nt_response = data_blob(NULL, 24); DATA_BLOB session_key = data_blob(NULL, 16); uchar lm_key[8]; uchar user_session_key[16]; uchar lm_hash[16]; uchar nt_hash[16]; DATA_BLOB chall = get_challenge(); char *error_string; ZERO_STRUCT(lm_key); ZERO_STRUCT(user_session_key); flags |= WBFLAG_PAM_LMKEY; flags |= WBFLAG_PAM_USER_SESSION_KEY; SMBencrypt(opt_password,chall.data,lm_response.data); E_deshash(opt_password, lm_hash); SMBNTencrypt(opt_password,chall.data,nt_response.data); E_md4hash(opt_password, nt_hash); SMBsesskeygen_ntv1(nt_hash, NULL, session_key.data); switch (break_which) { case BREAK_NONE: break; case BREAK_LM: lm_response.data[0]++; break; case BREAK_NT: nt_response.data[0]++; break; case NO_LM: data_blob_free(&lm_response); break; case NO_NT: data_blob_free(&nt_response); break; } nt_status = contact_winbind_auth_crap(opt_username, opt_domain, opt_workstation, &chall, &lm_response, &nt_response, flags, lm_key, user_session_key, &error_string, NULL); data_blob_free(&lm_response); if (!NT_STATUS_IS_OK(nt_status)) { d_printf("%s (0x%x)\n", error_string, NT_STATUS_V(nt_status)); SAFE_FREE(error_string); return break_which == BREAK_NT; } if (memcmp(lm_hash, lm_key, sizeof(lm_key)) != 0) { DEBUG(1, ("LM Key does not match expectations!\n")); DEBUG(1, ("lm_key:\n")); dump_data(1, (const char *)lm_key, 8); DEBUG(1, ("expected:\n")); dump_data(1, (const char *)lm_hash, 8); pass = False; } if (break_which == NO_NT) { if (memcmp(lm_hash, user_session_key, 8) != 0) { DEBUG(1, ("NT Session Key does not match expectations (should be LM hash)!\n")); DEBUG(1, ("user_session_key:\n")); dump_data(1, (const char *)user_session_key, sizeof(user_session_key)); DEBUG(1, ("expected:\n")); dump_data(1, (const char *)lm_hash, sizeof(lm_hash)); pass = False; } } else { if (memcmp(session_key.data, user_session_key, sizeof(user_session_key)) != 0) { DEBUG(1, ("NT Session Key does not match expectations!\n")); DEBUG(1, ("user_session_key:\n")); dump_data(1, (const char *)user_session_key, 16); DEBUG(1, ("expected:\n")); dump_data(1, (const char *)session_key.data, session_key.length); pass = False; } } return pass; }
NTSTATUS gensec_ntlmssp_server_negotiate(struct gensec_security *gensec_security, TALLOC_CTX *out_mem_ctx, const DATA_BLOB request, DATA_BLOB *reply) { struct gensec_ntlmssp_context *gensec_ntlmssp = talloc_get_type_abort(gensec_security->private_data, struct gensec_ntlmssp_context); struct ntlmssp_state *ntlmssp_state = gensec_ntlmssp->ntlmssp_state; struct auth4_context *auth_context = gensec_security->auth_context; DATA_BLOB struct_blob; uint32_t neg_flags = 0; uint32_t ntlmssp_command, chal_flags; uint8_t cryptkey[8]; const char *target_name; NTSTATUS status; /* parse the NTLMSSP packet */ #if 0 file_save("ntlmssp_negotiate.dat", request.data, request.length); #endif if (request.length) { if ((request.length < 16) || !msrpc_parse(ntlmssp_state, &request, "Cdd", "NTLMSSP", &ntlmssp_command, &neg_flags)) { DEBUG(1, ("ntlmssp_server_negotiate: failed to parse NTLMSSP Negotiate of length %u\n", (unsigned int)request.length)); dump_data(2, request.data, request.length); return NT_STATUS_INVALID_PARAMETER; } debug_ntlmssp_flags(neg_flags); if (DEBUGLEVEL >= 10) { struct NEGOTIATE_MESSAGE *negotiate = talloc( ntlmssp_state, struct NEGOTIATE_MESSAGE); if (negotiate != NULL) { status = ntlmssp_pull_NEGOTIATE_MESSAGE( &request, negotiate, negotiate); if (NT_STATUS_IS_OK(status)) { NDR_PRINT_DEBUG(NEGOTIATE_MESSAGE, negotiate); } TALLOC_FREE(negotiate); } } } ntlmssp_handle_neg_flags(ntlmssp_state, neg_flags, ntlmssp_state->allow_lm_key); /* Ask our caller what challenge they would like in the packet */ if (auth_context->get_ntlm_challenge) { status = auth_context->get_ntlm_challenge(auth_context, cryptkey); if (!NT_STATUS_IS_OK(status)) { DEBUG(1, ("gensec_ntlmssp_server_negotiate: failed to get challenge: %s\n", nt_errstr(status))); return status; } } else { DEBUG(1, ("gensec_ntlmssp_server_negotiate: backend doesn't give a challenge\n")); return NT_STATUS_NOT_IMPLEMENTED; } /* The flags we send back are not just the negotiated flags, * they are also 'what is in this packet'. Therfore, we * operate on 'chal_flags' from here on */ chal_flags = ntlmssp_state->neg_flags; /* get the right name to fill in as 'target' */ target_name = ntlmssp_target_name(ntlmssp_state, neg_flags, &chal_flags); if (target_name == NULL) return NT_STATUS_INVALID_PARAMETER; ntlmssp_state->chal = data_blob_talloc(ntlmssp_state, cryptkey, 8); ntlmssp_state->internal_chal = data_blob_talloc(ntlmssp_state, cryptkey, 8); /* This creates the 'blob' of names that appears at the end of the packet */ if (chal_flags & NTLMSSP_NEGOTIATE_TARGET_INFO) { status = msrpc_gen(ntlmssp_state, &struct_blob, "aaaaa", MsvAvNbDomainName, target_name, MsvAvNbComputerName, ntlmssp_state->server.netbios_name, MsvAvDnsDomainName, ntlmssp_state->server.dns_domain, MsvAvDnsComputerName, ntlmssp_state->server.dns_name, MsvAvEOL, ""); if (!NT_STATUS_IS_OK(status)) { return status; } } else { struct_blob = data_blob_null; } { /* Marshal the packet in the right format, be it unicode or ASCII */ const char *gen_string; DATA_BLOB version_blob = data_blob_null; if (chal_flags & NTLMSSP_NEGOTIATE_VERSION) { enum ndr_err_code err; struct ntlmssp_VERSION vers; /* "What Windows returns" as a version number. */ ZERO_STRUCT(vers); vers.ProductMajorVersion = NTLMSSP_WINDOWS_MAJOR_VERSION_6; vers.ProductMinorVersion = NTLMSSP_WINDOWS_MINOR_VERSION_1; vers.ProductBuild = 0; vers.NTLMRevisionCurrent = NTLMSSP_REVISION_W2K3; err = ndr_push_struct_blob(&version_blob, ntlmssp_state, &vers, (ndr_push_flags_fn_t)ndr_push_ntlmssp_VERSION); if (!NDR_ERR_CODE_IS_SUCCESS(err)) { data_blob_free(&struct_blob); return NT_STATUS_NO_MEMORY; } } if (ntlmssp_state->unicode) { gen_string = "CdUdbddBb"; } else { gen_string = "CdAdbddBb"; } status = msrpc_gen(out_mem_ctx, reply, gen_string, "NTLMSSP", NTLMSSP_CHALLENGE, target_name, chal_flags, cryptkey, 8, 0, 0, struct_blob.data, struct_blob.length, version_blob.data, version_blob.length); if (!NT_STATUS_IS_OK(status)) { data_blob_free(&version_blob); data_blob_free(&struct_blob); return status; } data_blob_free(&version_blob); if (DEBUGLEVEL >= 10) { struct CHALLENGE_MESSAGE *challenge = talloc( ntlmssp_state, struct CHALLENGE_MESSAGE); if (challenge != NULL) { challenge->NegotiateFlags = chal_flags; status = ntlmssp_pull_CHALLENGE_MESSAGE( reply, challenge, challenge); if (NT_STATUS_IS_OK(status)) { NDR_PRINT_DEBUG(CHALLENGE_MESSAGE, challenge); } TALLOC_FREE(challenge); } } } data_blob_free(&struct_blob); ntlmssp_state->expected_state = NTLMSSP_AUTH; return NT_STATUS_MORE_PROCESSING_REQUIRED; }
int main() { int np = 9; /* number of points on the sheet */ double dt = .005; int step = 0; double time = 0.0; double *de, *x, *y, *gamma; double c[4]; /* int j; */ /* double sumg; */ char fname[30]; int dump_num = 0; double dump_time = 1; /* double max; */ /* double sum; */ /* FILE *dump; */ /* double mindist = SQR(.5/np); */ /* double maxdist = SQR(1.5/np); */ get_physical_params(c); de = vector(np); x = vector(np); y = vector(np); gamma = vector(np); init_sheet(de, x, y, gamma, np, 2.0*c[3]); /* getchar(); */ /* dump = fopen("max2.dat", "w"); */ while(1) { if(time >= dump_time * dump_num) { sprintf(fname, "sheet_%03i.dat", dump_num); dump_data(de, x, y, gamma, np, c, time, dt, fname); dump_num++; } step++; time += dt; /*printf("\x1B[2J");*/ /* printf("**** ");*/ /* printf("Step: %5i Time: %8.5f (%8.5f s) (dt = %9.4g)\n", */ /* step, time, realtime, dt); */ /* printf(" *****\n");*/ /* printf("Gamma before step:\t%f\n", integral(gamma,de,np)-1.0); */ dt = do_timestep(de, &x, &y, &gamma, c, np, dt); /* printf("Gamma before trim:\t%f\n", integral(gamma,de,np)-1.0); */ /* np = trim_distances(&de, &x, &y, &gamma, mindist, maxdist, np); */ /* printf("Gamma after (%i):\t%f\n\n", np,integral(gamma,de,np)-1.0); */ /* printf("Smooth x: "); */ /* fourier_smooth(x, np); */ /* printf("Smooth y: "); */ /* fourier_smooth(y, np); */ /* sum = integral(gamma,de,np)-1.0; */ /* if(fabs(sum) > 1e-12) { */ /* printf("Step: %i Gamma: %e\n", step, sum); */ /* getchar(); */ /* } */ /* getchar(); */ /* sumg = 0.0; */ /* for(j = 0; j < np; j++) */ /* sumg += gamma[j]*de[j]; */ /* printf("np: %3i\nSum g: %9.5e\n", np, sumg-1); */ /* max = dump_data(x, y, gamma, np, "sheet2.dat"); */ /* fprintf(dump, "%f\t%f\n", realtime, max); */ /* getchar(); */ } /* fclose(dump); */ return 0; }
int http_transfer(UrlResource *rsrc, libnet_callback notify) { FILE *out = NULL; Url *u = NULL; Url *proxy_url = NULL; Url *redir_u = NULL; char *request = NULL; //char *raw_header = NULL; HttpHeader *header = NULL; //char *len_string = NULL; //char *new_location = NULL; char *tmp_string = NULL; //char buf[BUFSIZE]; int sock = -1; ssize_t bytes_read = 0; int msg_code = 0; int retval = 0; int i; char *buf = MALLOC(BUFSIZE); if (!buf) { LIBNET_DEBUG("No enough memory!\n"); return 0; } /* make sure we haven't recursed too much */ if ( redirect_count > REDIRECT_MAX ) { LIBNET_DEBUG("redirection max count exceeded (looping redirect?)"); redirect_count = 0; msg_code = -NET_ERR_CONNECT_FAILED; goto cleanup; } /* make sure everything's initialized to something useful */ u = rsrc->url; if ( !u->host ) { LIBNET_DEBUG("no host specified"); msg_code = -NET_ERR_CONNECT_FAILED; goto cleanup; } /* fill in proxyness */ if ( !rsrc->proxy ) { rsrc->proxy = get_proxy("HTTP_PROXY"); } if (( NULL == rsrc->outfile ) && (NULL == rsrc->buffer)) { if ( u->file ) rsrc->outfile = strdup(u->file); else rsrc->outfile = strdup("index.html"); } if ( !u->path ) u->path = strdup("/"); if ( !u->file ) u->file = strdup(""); /* funny looking */ if ( !u->port ) u->port = 80; rsrc->options |= default_opts; /* send the request to either the proxy or the remote host */ if ( rsrc->proxy ) { proxy_url = url_new(); url_init(proxy_url, rsrc->proxy); if ( !proxy_url->port ) proxy_url->port = 80; if ( !proxy_url->host ) { LIBNET_DEBUG( "bad proxy `%s'", rsrc->proxy); msg_code = -NET_ERR_CONNECT_FAILED; goto cleanup; } if ( proxy_url->username ) rsrc->proxy_username = strdup(proxy_url->username); if ( proxy_url->password ) rsrc->proxy_password = strdup(proxy_url->password); #ifdef LIB_W5300 sock = w5300_tcp_connect(proxy_url->host, proxy_url->port, rsrc->srcip, rsrc->srcport); #else sock = util_tcp_connect(proxy_url->host, proxy_url->port); #endif if (sock < 0) { msg_code = -NET_ERR_CONNECT_FAILED; goto cleanup; } safe_free(u->path); safe_free(u->file); u->path = strdup(""); u->file = strdup(u->full_url); request = get_request(rsrc); LIBNET_DEBUG("sending request:\n%s", request); S_WRITE(sock, request, STRLEN(request)); FREE(request); } else /* no proxy */ { #ifdef LIB_W5300 sock = w5300_tcp_connect(u->host, u->port, rsrc->srcip, rsrc->srcport); #else sock = util_tcp_connect(u->host, u->port); #endif if (sock < 0) { msg_code = -NET_ERR_CONNECT_FAILED; goto cleanup; } request = get_request(rsrc); LIBNET_DEBUG("sending request:\n%s", request); S_WRITE(sock, request, STRLEN(request)); FREE(request); } if (rsrc->outfile) { if ((get_file_size(rsrc->outfile) > 0) && (rsrc->options & OPT_RESUME)) out = fopen(rsrc->outfile, "rb+"); else out = fopen(rsrc->outfile, "wb"); if ( !out ) { LIBNET_DEBUG( "opening %s: %s", rsrc->outfile, ""); msg_code = -NET_ERR_FILE_SAVE_ERROR; goto cleanup; } } /* check to see if it returned a HTTP 1.x response */ MEMSET(buf, '\0', 5); #ifdef LIB_W5300 bytes_read = S_READ(sock, buf, BUFSIZE); buf[bytes_read] = '\0'; LIBNET_DEBUG("receive respond:(%d)\n%s", bytes_read, buf); #else bytes_read = S_READ(sock, buf, 8); #endif if ( bytes_read <= 0 ) { msg_code = -NET_ERR_HTTP_SERVER_ERROR; goto cleanup; } if ( ! (buf[0] == 'H' && buf[1] == 'T' && buf[2] == 'T' && buf[3] == 'P') ) { if((rsrc->options & OPT_RESUME) && rsrc->outfile_offset) { LIBNET_DEBUG("server does not support resume!"); msg_code = -NET_ERR_OPERATION_NOT_PERMIT; goto cleanup; } //fwrite(buf, bytes_read, 1,out); } else { /* skip the header */ #ifdef LIB_W5300 buf[bytes_read] = '\0'; #else char *raw_header1 = NULL; buf[bytes_read] = '\0'; raw_header1 = get_raw_header(sock); strconcat2(buf, raw_header1, NULL); FREE(raw_header1); LIBNET_DEBUG("receive respond:(%d)\n%s", bytes_read, buf); #endif header = make_http_header(buf); /* check for redirects */ tmp_string = get_header_value("location", header); if (buf[9] == '3' && tmp_string ) { #if 1 //diable redirec function redir_u = url_new(); /* make sure we still send user/password along */ redir_u->username = safe_strdup(u->username); redir_u->password = safe_strdup(u->password); url_init(redir_u, tmp_string); rsrc->url = redir_u; redirect_count++; //retval = transfer(rsrc, notify); transfer((UINT32)rsrc, (UINT32)notify); rsrc->url =u; redirect_count--; if(redirect_count<0) redirect_count=0; if (redir_u) { url_destroy(redir_u); FREE(redir_u); } #endif FREE(tmp_string); tmp_string = NULL; //msg_code = -NET_ERR_OPERATION_NOT_PERMIT;//we can support redirect now, remove this line. goto cleanup; } if (tmp_string) { FREE(tmp_string); tmp_string = NULL; } if (buf[9] == '4' || buf[9] == '5') { for (i = 0; buf[i] && buf[i] != '\n'; i++); buf[i] = '\0'; LIBNET_DEBUG("HTTP error from server: %s\n", buf); if( buf[9] == '4' && buf[10] == '0' && buf[11] == '4') msg_code = -NET_ERR_FILE_NOT_FOUND; else msg_code = -NET_ERR_HTTP_SERVER_ERROR; goto cleanup; } tmp_string = get_header_value("content-length", header); if (tmp_string) { rsrc->outfile_size = (off_t )ATOI(tmp_string); FREE(tmp_string); tmp_string = NULL; if(rsrc->use_pecache ==0) { if ((rsrc->buffer) && (rsrc->buffer_len < rsrc->outfile_size)) { LIBNET_DEBUG("the buffer length less than the file fize (%d < %d)\n", rsrc->buffer, (int)rsrc->outfile_size); msg_code = -NET_ERR_FILE_SAVE_ERROR; goto cleanup; } } } tmp_string = get_header_value("content-range", header); if (tmp_string) { FREE(tmp_string); tmp_string = NULL; rsrc->outfile_size += rsrc->outfile_offset; } if ((!rsrc->outfile_size) && (rsrc->options & OPT_RESUME) && !(rsrc->options & OPT_NORESUME) && rsrc->outfile_offset ) { LIBNET_DEBUG("unable to determine remote file size"); msg_code = -NET_ERR_FILE_SAVE_ERROR; goto cleanup; } } if(rsrc->use_pecache ==0) retval = dump_data(rsrc, sock, out, notify); else retval = dump_data_to_pecache(rsrc, sock, out, notify); cleanup: free_http_header(header); //if (raw_header) // FREE(raw_header); if (proxy_url) { url_destroy(proxy_url); FREE(proxy_url); } if (sock >= 0) { S_CLOSE(sock); } if (out) fclose(out); if (buf) { FREE(buf); } #ifndef WIN32 if (rsrc->outfile) fs_sync(rsrc->outfile); #endif if (msg_code < 0 && rsrc->running) { notify(NET_MSG_DOWNLOAD_FINISH, (UINT32)msg_code); libnet_abort_url_read(TRUE);//to break url_open while loop //retval!=1 means transfer fail } return retval; }
static bool api_rpcTNP(struct pipes_struct *p, struct ncacn_packet *pkt, const struct api_struct *api_rpc_cmds, int n_cmds, const struct ndr_syntax_id *syntax) { int fn_num; uint32_t offset1; const struct ndr_interface_table *table; /* interpret the command */ DEBUG(4,("api_rpcTNP: %s op 0x%x - ", ndr_interface_name(&syntax->uuid, syntax->if_version), pkt->u.request.opnum)); table = ndr_table_by_uuid(&syntax->uuid); if (table == NULL) { DEBUG(0,("unknown interface\n")); return false; } if (DEBUGLEVEL >= 50) { fstring name; slprintf(name, sizeof(name)-1, "in_%s", dcerpc_default_transport_endpoint(pkt, NCACN_NP, table)); dump_pdu_region(name, pkt->u.request.opnum, &p->in_data.data, 0, p->in_data.data.length); } for (fn_num = 0; fn_num < n_cmds; fn_num++) { if (api_rpc_cmds[fn_num].opnum == pkt->u.request.opnum && api_rpc_cmds[fn_num].fn != NULL) { DEBUG(3, ("api_rpcTNP: rpc command: %s\n", api_rpc_cmds[fn_num].name)); break; } } if (fn_num == n_cmds) { /* * For an unknown RPC just return a fault PDU but * return True to allow RPC's on the pipe to continue * and not put the pipe into fault state. JRA. */ DEBUG(4, ("unknown\n")); setup_fault_pdu(p, NT_STATUS(DCERPC_FAULT_OP_RNG_ERROR)); return True; } offset1 = p->out_data.rdata.length; DEBUG(6, ("api_rpc_cmds[%d].fn == %p\n", fn_num, api_rpc_cmds[fn_num].fn)); /* do the actual command */ if(!api_rpc_cmds[fn_num].fn(p)) { DEBUG(0,("api_rpcTNP: %s: %s failed.\n", ndr_interface_name(&syntax->uuid, syntax->if_version), api_rpc_cmds[fn_num].name)); data_blob_free(&p->out_data.rdata); return False; } if (p->fault_state) { DEBUG(4,("api_rpcTNP: fault(%d) return.\n", p->fault_state)); setup_fault_pdu(p, NT_STATUS(p->fault_state)); p->fault_state = 0; return true; } if (DEBUGLEVEL >= 50) { fstring name; slprintf(name, sizeof(name)-1, "out_%s", dcerpc_default_transport_endpoint(pkt, NCACN_NP, table)); dump_pdu_region(name, pkt->u.request.opnum, &p->out_data.rdata, offset1, p->out_data.rdata.length); } DEBUG(5,("api_rpcTNP: called %s successfully\n", ndr_interface_name(&syntax->uuid, syntax->if_version))); /* Check for buffer underflow in rpc parsing */ if ((DEBUGLEVEL >= 10) && (pkt->frag_length < p->in_data.data.length)) { DEBUG(10, ("api_rpcTNP: rpc input buffer underflow (parse error?)\n")); dump_data(10, p->in_data.data.data + pkt->frag_length, p->in_data.data.length - pkt->frag_length); } return True; }
void dump_client_packet(FILE *file, int fd, int packet_len) { unsigned int packet_id = RFIFOW(fd, 0); fprintf(file, "client packet: 0x%x %u, len: %d\n", packet_id, packet_id, packet_len); dump_data(file, fd, packet_len); }
/* This uses the test values from rfc 4493 */ bool torture_local_crypto_aes_cmac_128(struct torture_context *torture) { bool ret = true; uint32_t i; DATA_BLOB key; struct { DATA_BLOB data; DATA_BLOB cmac; } testarray[5]; TALLOC_CTX *tctx = talloc_new(torture); if (!tctx) { return false; }; key = strhex_to_data_blob(tctx, "2b7e151628aed2a6abf7158809cf4f3c"); testarray[0].data = data_blob_null; testarray[0].cmac = strhex_to_data_blob(tctx, "bb1d6929e95937287fa37d129b756746"); testarray[1].data = strhex_to_data_blob(tctx, "6bc1bee22e409f96e93d7e117393172a"); testarray[1].cmac = strhex_to_data_blob(tctx, "070a16b46b4d4144f79bdd9dd04a287c"); testarray[2].data = strhex_to_data_blob(tctx, "6bc1bee22e409f96e93d7e117393172a" "ae2d8a571e03ac9c9eb76fac45af8e51" "30c81c46a35ce411"); testarray[2].cmac = strhex_to_data_blob(tctx, "dfa66747de9ae63030ca32611497c827"); testarray[3].data = strhex_to_data_blob(tctx, "6bc1bee22e409f96e93d7e117393172a" "ae2d8a571e03ac9c9eb76fac45af8e51" "30c81c46a35ce411e5fbc1191a0a52ef" "f69f2445df4f9b17ad2b417be66c3710"); testarray[3].cmac = strhex_to_data_blob(tctx, "51f0bebf7e3b9d92fc49741779363cfe"); ZERO_STRUCT(testarray[4]); for (i=0; testarray[i].cmac.length != 0; i++) { struct aes_cmac_128_context ctx; uint8_t cmac[AES_BLOCK_SIZE]; int e; aes_cmac_128_init(&ctx, key.data); aes_cmac_128_update(&ctx, testarray[i].data.data, testarray[i].data.length); aes_cmac_128_final(&ctx, cmac); e = memcmp(testarray[i].cmac.data, cmac, sizeof(cmac)); if (e != 0) { printf("aes_cmac_128 test[%u]: failed\n", i); dump_data(0, key.data, key.length); dump_data(0, testarray[i].data.data, testarray[i].data.length); dump_data(0, testarray[i].cmac.data, testarray[i].cmac.length); dump_data(0, cmac, sizeof(cmac)); ret = false; } } for (i=0; testarray[i].cmac.length != 0; i++) { struct aes_cmac_128_context ctx; uint8_t cmac[AES_BLOCK_SIZE]; int e; size_t j; aes_cmac_128_init(&ctx, key.data); for (j=0; j < testarray[i].data.length; j++) { aes_cmac_128_update(&ctx, NULL, 0); aes_cmac_128_update(&ctx, &testarray[i].data.data[j], 1); aes_cmac_128_update(&ctx, NULL, 0); } aes_cmac_128_final(&ctx, cmac); e = memcmp(testarray[i].cmac.data, cmac, sizeof(cmac)); if (e != 0) { printf("aes_cmac_128 chunked test[%u]: failed\n", i); dump_data(0, key.data, key.length); dump_data(0, testarray[i].data.data, testarray[i].data.length); dump_data(0, testarray[i].cmac.data, testarray[i].cmac.length); dump_data(0, cmac, sizeof(cmac)); ret = false; } } talloc_free(tctx); return ret; }
void x86emu_dump(x86emu_t *emu, int flags) { x86emu_mem_t *mem = emu->mem; mem2_pdir_t *pdir; mem2_ptable_t *ptable; mem2_page_t page; unsigned pdir_idx, u, u1, u2, addr; char str_data[LINE_LEN * 8], str_attr[LINE_LEN * 8], fbuf[64]; unsigned char def_data[LINE_LEN], def_attr[LINE_LEN]; int dump_flags; if( mem && mem->pdir && (flags & (X86EMU_DUMP_MEM | X86EMU_DUMP_ACC_MEM | X86EMU_DUMP_INV_MEM | X86EMU_DUMP_ATTR)) ) { x86emu_log(emu, "; - - memory\n"); x86emu_log(emu, "; "); for(u1 = 0; u1 < 16; u1++) x86emu_log(emu, "%4x", u1); x86emu_log(emu, "\n"); dump_flags = 0; if(flags & X86EMU_DUMP_INV_MEM) dump_flags = 2; if(flags & X86EMU_DUMP_ACC_MEM) dump_flags = 1; if(flags & X86EMU_DUMP_MEM) dump_flags = 0; if(flags & X86EMU_DUMP_ASCII) dump_flags |= 0x100; pdir = mem->pdir; for(pdir_idx = 0; pdir_idx < (1 << X86EMU_PDIR_BITS); pdir_idx++) { ptable = (*pdir)[pdir_idx]; if(!ptable) continue; for(u1 = 0; u1 < (1 << X86EMU_PTABLE_BITS); u1++) { page = (*ptable)[u1]; if(page.data) { for(u2 = 0; u2 < X86EMU_PAGE_SIZE; u2 += LINE_LEN) { memcpy(def_data, page.data + u2, LINE_LEN); if(page.attr) { memcpy(def_attr, page.attr + u2, LINE_LEN); } else { memset(def_attr, page.def_attr, LINE_LEN); } dump_data(def_data, def_attr, str_data, str_attr, dump_flags); if(*str_data) { addr = (((pdir_idx << X86EMU_PTABLE_BITS) + u1) << X86EMU_PAGE_BITS) + u2; x86emu_log(emu, "%08x: %s\n", addr, str_data); if((flags & X86EMU_DUMP_ATTR)) x86emu_log(emu, " %s\n", str_attr); } } } } } x86emu_log(emu, "\n"); } if((flags & X86EMU_DUMP_IO)) { x86emu_log(emu, "; - - io accesses\n"); for(u = 0; u < X86EMU_IO_PORTS; u++) { if(emu->io.map[u] & (X86EMU_ACC_R | X86EMU_ACC_W | X86EMU_ACC_INVALID)) { x86emu_log(emu, "%04x: %c%c%c in=%08x out=%08x\n", u, (emu->io.map[u] & X86EMU_ACC_INVALID) ? '*' : ' ', (emu->io.map[u] & X86EMU_PERM_R) ? 'r' : ' ', (emu->io.map[u] & X86EMU_PERM_W) ? 'w' : ' ', emu->io.stats_i[u], emu->io.stats_o[u] ); } } x86emu_log(emu, "\n"); } if((flags & X86EMU_DUMP_INTS)) { x86emu_log(emu, "; - - interrupt statistics\n"); for(u1 = 0; u1 < 0x100; u1++) { if(emu->x86.intr_stats[u1]) x86emu_log(emu, "int %02x: %08x\n", u1, emu->x86.intr_stats[u1]); } x86emu_log(emu, "\n"); } if((flags & X86EMU_DUMP_REGS)) { x86emu_log(emu, "; - - registers\n"); for(u = u1 = 0; u < X86EMU_MSRS; u++) { if(u >= 0x11 && u <= 0x12 && !(flags & X86EMU_DUMP_TIME)) continue; if(emu->x86.msr_perm[u]) { u1 = 1; x86emu_log(emu, "msr[%04x] %c%c %016llx", u, (emu->x86.msr_perm[u] & X86EMU_ACC_R) ? 'r' : ' ', (emu->x86.msr_perm[u] & X86EMU_ACC_W) ? 'w' : ' ', (unsigned long long) emu->x86.msr[u] ); switch(u) { case 0x10: x86emu_log(emu, " ; tsc"); break; case 0x11: x86emu_log(emu, " ; real tsc (previous)"); break; case 0x12: x86emu_log(emu, " ; real tsc"); if(emu->x86.R_TSC) { x86emu_log(emu, ", ratio=%.2f", (double) emu->x86.R_REAL_TSC / emu->x86.R_TSC); } break; } x86emu_log(emu, "\n"); } } if(u1) x86emu_log(emu, "\n"); x86emu_log(emu, "cr0=%08x cr1=%08x cr2=%08x cr3=%08x cr4=%08x\n", emu->x86.R_CR0, emu->x86.R_CR1, emu->x86.R_CR2, emu->x86.R_CR3, emu->x86.R_CR4 ); x86emu_log(emu, "dr0=%08x dr1=%08x dr2=%08x dr3=%08x dr6=%08x dr7=%08x\n\n", emu->x86.R_DR0, emu->x86.R_DR1, emu->x86.R_DR2, emu->x86.R_DR3, emu->x86.R_DR6, emu->x86.R_DR7 ); x86emu_log(emu, "gdt.base=%08x gdt.limit=%04x\n", emu->x86.R_GDT_BASE, emu->x86.R_GDT_LIMIT ); x86emu_log(emu, "idt.base=%08x idt.limit=%04x\n", emu->x86.R_IDT_BASE, emu->x86.R_IDT_LIMIT ); x86emu_log(emu, "tr=%04x tr.base=%08x tr.limit=%08x tr.acc=%04x\n", emu->x86.R_TR, emu->x86.R_TR_BASE, emu->x86.R_TR_LIMIT, emu->x86.R_TR_ACC ); x86emu_log(emu, "ldt=%04x ldt.base=%08x ldt.limit=%08x ldt.acc=%04x\n\n", emu->x86.R_LDT, emu->x86.R_LDT_BASE, emu->x86.R_LDT_LIMIT, emu->x86.R_LDT_ACC ); x86emu_log(emu, "cs=%04x cs.base=%08x cs.limit=%08x cs.acc=%04x\n", emu->x86.R_CS, emu->x86.R_CS_BASE, emu->x86.R_CS_LIMIT, emu->x86.R_CS_ACC ); x86emu_log(emu, "ss=%04x ss.base=%08x ss.limit=%08x ss.acc=%04x\n", emu->x86.R_SS, emu->x86.R_SS_BASE, emu->x86.R_SS_LIMIT, emu->x86.R_SS_ACC ); x86emu_log(emu, "ds=%04x ds.base=%08x ds.limit=%08x ds.acc=%04x\n", emu->x86.R_DS, emu->x86.R_DS_BASE, emu->x86.R_DS_LIMIT, emu->x86.R_DS_ACC ); x86emu_log(emu, "es=%04x es.base=%08x es.limit=%08x es.acc=%04x\n", emu->x86.R_ES, emu->x86.R_ES_BASE, emu->x86.R_ES_LIMIT, emu->x86.R_ES_ACC ); x86emu_log(emu, "fs=%04x fs.base=%08x fs.limit=%08x fs.acc=%04x\n", emu->x86.R_FS, emu->x86.R_FS_BASE, emu->x86.R_FS_LIMIT, emu->x86.R_FS_ACC ); x86emu_log(emu, "gs=%04x gs.base=%08x gs.limit=%08x gs.acc=%04x\n\n", emu->x86.R_GS, emu->x86.R_GS_BASE, emu->x86.R_GS_LIMIT, emu->x86.R_GS_ACC ); x86emu_log(emu, "eax=%08x ebx=%08x ecx=%08x edx=%08x\n", emu->x86.R_EAX, emu->x86.R_EBX, emu->x86.R_ECX, emu->x86.R_EDX ); x86emu_log(emu, "esi=%08x edi=%08x ebp=%08x esp=%08x\n", emu->x86.R_ESI, emu->x86.R_EDI, emu->x86.R_EBP, emu->x86.R_ESP ); x86emu_log(emu, "eip=%08x eflags=%08x", emu->x86.R_EIP, emu->x86.R_EFLG); *fbuf = 0; if(emu->x86.R_EFLG & 0x800) strcat(fbuf, " of"); if(emu->x86.R_EFLG & 0x400) strcat(fbuf, " df"); if(emu->x86.R_EFLG & 0x200) strcat(fbuf, " if"); if(emu->x86.R_EFLG & 0x080) strcat(fbuf, " sf"); if(emu->x86.R_EFLG & 0x040) strcat(fbuf, " zf"); if(emu->x86.R_EFLG & 0x010) strcat(fbuf, " af"); if(emu->x86.R_EFLG & 0x004) strcat(fbuf, " pf"); if(emu->x86.R_EFLG & 0x001) strcat(fbuf, " cf"); if(*fbuf) x86emu_log(emu, " ;%s", fbuf); x86emu_log(emu, "\n\n"); } }
static NTSTATUS ntlmssp_server_negotiate(struct ntlmssp_state *ntlmssp_state, const DATA_BLOB request, DATA_BLOB *reply) { DATA_BLOB struct_blob; fstring dnsname, dnsdomname; uint32 neg_flags = 0; uint32 ntlmssp_command, chal_flags; char *cliname=NULL, *domname=NULL; const uint8 *cryptkey; const char *target_name; /* parse the NTLMSSP packet */ #if 0 file_save("ntlmssp_negotiate.dat", request.data, request.length); #endif if (request.length) { if (!msrpc_parse(&request, "CddAA", "NTLMSSP", &ntlmssp_command, &neg_flags, &cliname, &domname)) { DEBUG(1, ("ntlmssp_server_negotiate: failed to parse NTLMSSP Negotiate:\n")); dump_data(2, (const char *)request.data, request.length); return NT_STATUS_INVALID_PARAMETER; } SAFE_FREE(cliname); SAFE_FREE(domname); debug_ntlmssp_flags(neg_flags); } ntlmssp_handle_neg_flags(ntlmssp_state, neg_flags, lp_lanman_auth()); /* Ask our caller what challenge they would like in the packet */ cryptkey = ntlmssp_state->get_challenge(ntlmssp_state); /* Check if we may set the challenge */ if (!ntlmssp_state->may_set_challenge(ntlmssp_state)) { ntlmssp_state->neg_flags &= ~NTLMSSP_NEGOTIATE_NTLM2; } /* The flags we send back are not just the negotiated flags, * they are also 'what is in this packet'. Therfore, we * operate on 'chal_flags' from here on */ chal_flags = ntlmssp_state->neg_flags; /* get the right name to fill in as 'target' */ target_name = ntlmssp_target_name(ntlmssp_state, neg_flags, &chal_flags); if (target_name == NULL) return NT_STATUS_INVALID_PARAMETER; ntlmssp_state->chal = data_blob_talloc(ntlmssp_state->mem_ctx, cryptkey, 8); ntlmssp_state->internal_chal = data_blob_talloc(ntlmssp_state->mem_ctx, cryptkey, 8); /* This should be a 'netbios domain -> DNS domain' mapping */ dnsdomname[0] = '\0'; //get_mydnsdomname(dnsdomname);//, peterLing, @access samba fast, 05/15/2009 strlower_m(dnsdomname); dnsname[0] = '\0'; //get_mydnsfullname(dnsname);//, peterLing, @access samba fast, 05/15/2009 /* This creates the 'blob' of names that appears at the end of the packet */ if (chal_flags & NTLMSSP_CHAL_TARGET_INFO) { msrpc_gen(&struct_blob, "aaaaa", NTLMSSP_NAME_TYPE_DOMAIN, target_name, NTLMSSP_NAME_TYPE_SERVER, ntlmssp_state->get_global_myname(), NTLMSSP_NAME_TYPE_DOMAIN_DNS, dnsdomname, NTLMSSP_NAME_TYPE_SERVER_DNS, dnsname, 0, ""); } else { struct_blob = data_blob(NULL, 0); } { /* Marshel the packet in the right format, be it unicode or ASCII */ const char *gen_string; if (ntlmssp_state->unicode) { gen_string = "CdUdbddB"; } else { gen_string = "CdAdbddB"; } msrpc_gen(reply, gen_string, "NTLMSSP", NTLMSSP_CHALLENGE, target_name, chal_flags, cryptkey, 8, 0, 0, struct_blob.data, struct_blob.length); } data_blob_free(&struct_blob); ntlmssp_state->expected_state = NTLMSSP_AUTH; return NT_STATUS_MORE_PROCESSING_REQUIRED; }
int do_work(ZWay zway) { print_help(); char cmd, cc_cmd, holder_root; ZWBYTE dev, inst, cc, cc_val, nconv; char data_path[256]; char cmd_buffer[256]; ZWBOOL was_idle = FALSE; ZWBOOL basic_level_attached = FALSE; int skip = 0; int running = TRUE; int level = 0; /* while(1){ digitalWrite(LED1,1); delay(500); digitalWrite(LED1,0); delay(500); }*/ while (running) { /* printf("\n\n\n"); zdata_acquire_lock(ZDataRoot(zway)); level = get_data(zway, zway_find_device_instance_cc_data(zway, '2', '0', 32, 'level')); zdata_release_lock(ZDataRoot(zway));*/ /* zdata_acquire_lock(ZDataRoot(zway)); level = get_data(zway, zway_find_device_data(zway, '1', 'level')); zdata_release_lock(ZDataRoot(zway)); */ printf("data ::::::: %d", int_val2); //zdata_add_callback(zway_find_device_instance_cc_data(zway,1,0,32,"mylevel"),[ZDataChangeCallback] callback, FALSE,[void*]arg); printf("\nLOG,while1\n"); if (!zway_is_running(zway)) //this is almost can not be execute { running = FALSE; break; } printf("\nLOG,while2\n"); if (!zway_is_idle(zway)) //maybe wait for { printf("\nLOG, sleep\n"); sleep_ms(10); continue; } skip = 0; /* printf("\nLOG,while3\n"); if (!basic_level_attached) { printf("\nLOG,basic level start\n"); ZDataHolder basic_level_holder; zdata_acquire_lock(ZDataRoot(zway)); basic_level_holder = zway_find_device_instance_cc_data(zway, 8, 0, 0x20, "mylevel"); // basic_level_holder = zway_find_device_instance_cc_data(zway, 8, 0, 0x26, "level"); if (basic_level_holder) { printf("\nLOG,basic level holder\n"); basic_level_attached = (zdata_add_callback(basic_level_holder, (ZDataChangeCallback) print_basic_holder, FALSE, NULL) == NoError); if (basic_level_attached){ zway_log(zway, Debug, ZSTR("Basic.data.mylevel holder handler attached to device 8 instance 0")); printf("\nLOG,basic level attatched\n"); } } zdata_release_lock(ZDataRoot(zway)); }*/ printf("\nLOG,while4\n"); if (!basic_level_attached) { printf("\nLOG,basic level start\n"); ZDataHolder basic_level_holder; zdata_acquire_lock(ZDataRoot(zway)); // basic_level_holder = zway_find_device_instance_cc_data(zway, 8, 0, 0x20, "mylevel"); basic_level_holder = zway_find_device_instance_cc_data(zway, 2, 0, 32, "level"); if (basic_level_holder) { printf("\nLOG,basic level holder\n"); basic_level_attached = (zdata_add_callback(basic_level_holder, (ZDataChangeCallback) print_basic_holder, FALSE, NULL) == NoError); if (basic_level_attached) { zway_log(zway, Debug, ZSTR( "Basic.data.mylevel holder handler attached to device 8 instance 0")); printf("\nLOG,basic level attatched\n"); pthread_create(&pthread, NULL, observer_function, NULL); pthread_detach(pthread); } } zdata_release_lock(ZDataRoot(zway)); } printf("> "); fgets(cmd_buffer, 255, stdin); was_idle = FALSE; nconv = sscanf(cmd_buffer, "%c %*s", &cmd); printf("nconv : %hhd", &nconv); if (nconv > 0) { switch (cmd) { case 'h': print_help(); break; case 'd': nconv = sscanf(cmd_buffer, "%c %c", &cmd, &holder_root); if (nconv > 1) { switch (holder_root) { case 'r': nconv = sscanf(cmd_buffer, "%c %c %s", &cmd, &holder_root, data_path); if (nconv >= 2) { if (nconv == 2) { data_path[0] = '.'; data_path[1] = '\0'; } zdata_acquire_lock(ZDataRoot(zway)); dump_data(zway, zway_find_controller_data(zway, data_path)); zdata_release_lock(ZDataRoot(zway)); } break; case 'd': nconv = sscanf(cmd_buffer, "%c %c %hhd %s", &cmd, &holder_root, &dev, data_path); if (nconv >= 3) { if (nconv == 3) { data_path[0] = '.'; data_path[1] = '\0'; } zdata_acquire_lock(ZDataRoot(zway)); dump_data(zway, zway_find_device_data(zway, dev, data_path)); zdata_release_lock(ZDataRoot(zway)); } break; case 'i': nconv = sscanf(cmd_buffer, "%c %c %hhd %hhd %s", &cmd, &holder_root, &dev, &inst, data_path); if (nconv >= 4) { if (nconv == 4) { data_path[0] = '.'; data_path[1] = '\0'; } zdata_acquire_lock(ZDataRoot(zway)); dump_data(zway, zway_find_device_instance_data(zway, dev, inst, data_path)); zdata_release_lock(ZDataRoot(zway)); } break; case 'c': nconv = sscanf(cmd_buffer, "%c %c %hhd %hhd %hhd %s", &cmd, &holder_root, &dev, &inst, &cc, data_path); if (nconv >= 5) { if (nconv == 5) { data_path[0] = '.'; data_path[1] = '\0'; } zdata_acquire_lock(ZDataRoot(zway)); dump_data(zway, zway_find_device_instance_cc_data(zway, dev, inst, cc, data_path)); zdata_release_lock(ZDataRoot(zway)); } break; } } break; case 's': nconv = sscanf(cmd_buffer, "%c %hhd %hhd %hhd %c %hhd", &cmd, &dev, &inst, &cc, &cc_cmd, &cc_val); printf("nconv : %hhd \n", &nconv); /* if (nconv == 6 && cmd == 's' && cc == 0x20 && cc_cmd == 's') { printf("nconv2 : %hhd \n",&nconv); printf("if gogo111111111111111111111111111111111111111111111111111111111111111111\n"); zdata_acquire_lock(ZDataRoot(zway)); zway_cc_switch_multilevel_set(zway, dev, inst, cc_val, 0x01 ,NULL ,NULL,0); zdata_release_lock(ZDataRoot(zway)); } else if (nconv == 5 && cmd == 's' && cc == 0x20 && cc_cmd == 'g') { printf("elseif gogo\n"); zdata_acquire_lock(ZDataRoot(zway)); zway_cc_switch_multilevel_get(zway, dev, inst,NULL,NULL,0); zdata_release_lock(ZDataRoot(zway)); } */ if (nconv == 6 && cmd == 's' && cc == 0x20 && cc_cmd == 's') { printf("nconv2 : %hhd \n", &nconv); printf( "if gogo111111111111111111111111111111111111111111111111111111111111111111\n"); zdata_acquire_lock(ZDataRoot(zway)); zway_cc_basic_set(zway, dev, inst, cc_val, NULL, NULL, NULL); zdata_release_lock(ZDataRoot(zway)); } else if (nconv == 5 && cmd == 's' && cc == 0x20 && cc_cmd == 'g') { printf("elseif gogo\n"); zdata_acquire_lock(ZDataRoot(zway)); zway_cc_basic_get(zway, dev, inst, NULL, NULL, NULL); zdata_release_lock(ZDataRoot(zway)); } else if (nconv == 6 && cmd == 's' && cc == 0x26 && cc_cmd == 's') { printf("nconv2 : %hhd \n", &nconv); printf( "if gogo333333333333333333333333333333333333333333333333333333333\n"); zdata_acquire_lock(ZDataRoot(zway)); zway_cc_switch_multilevel_set(zway, dev, inst, cc_val, 0x01, NULL, NULL, 0); zdata_release_lock(ZDataRoot(zway)); } break; case 'n': nconv = sscanf(cmd_buffer, "%c %hhd", &cmd, &dev); if (nconv == 2) zway_fc_request_node_information(zway, dev, NULL, NULL, NULL); break; case 'm': test_memory(zway); break; case 'a': zway_fc_add_node_to_network(zway, TRUE, TRUE, NULL, NULL, NULL); break; case 'A': zway_fc_add_node_to_network(zway, FALSE, TRUE, NULL, NULL, NULL); break; case 'e': zway_fc_remove_node_from_network(zway, TRUE, TRUE, NULL, NULL, NULL); break; case 'x': running = FALSE; break; case 'S': test_save(zway); break; case 'R': test_restore(zway); break; case 'q': // digitalWrite(LED1, 1); break; case 'w': // digitalWrite(LED1, 0); break; case 'l': nconv = sscanf(cmd_buffer, "%c %hhd %hhd", &cmd, &dev, &inst); switch (nconv) { case 1: { ZWDevicesList list = zway_devices_list(zway); if (list != NULL) { int i = 0; printf("Devices list: "); while (list[i]) { printf("%i ", list[i]); i++; } zway_devices_list_free(list); printf("\n"); } else printf("Error happened requesting devices list\n"); } break; case 2: { ZWInstancesList list = zway_instances_list(zway, dev); if (list != NULL) { int i = 0; printf("Instances list for device %i: ", dev); while (list[i]) { printf("%i ", list[i]); i++; } zway_instances_list_free(list); printf("\n"); } else printf("Error happened requesting instances list\n"); } break; case 3: { ZWCommandClassesList list = zway_command_classes_list(zway, dev, inst); if (list != NULL) { int i = 0; printf( "Command Classes list for device %i instance %i: ", dev, inst); while (list[i]) { printf("%02x ", list[i]); i++; } zway_command_classes_list_free(list); printf("\n"); } else printf( "Error happened requesting command classes list\n"); } break; } break; } } } return 0; }
static NTSTATUS ntlmssp_server_auth(struct ntlmssp_state *ntlmssp_state, const DATA_BLOB request, DATA_BLOB *reply) { DATA_BLOB encrypted_session_key = data_blob(NULL, 0); DATA_BLOB user_session_key = data_blob(NULL, 0); DATA_BLOB lm_session_key = data_blob(NULL, 0); DATA_BLOB session_key = data_blob(NULL, 0); uint32 ntlmssp_command, auth_flags; NTSTATUS nt_status; /* used by NTLM2 */ BOOL doing_ntlm2 = False; uchar session_nonce[16]; uchar session_nonce_hash[16]; const char *parse_string; char *domain = NULL; char *user = NULL; char *workstation = NULL; /* add start, water, 11/17/2008*/ /*when security=share, the samba doesn't workable, now set security=user, but does not check username & password*/ FILE* fp = NULL; char TmpUsr[6] = "guest";/*If all shared folders are 'All - no password', then no need to login for "HTTP", "FTP" or samba.*/ /* add end, water, 11/17/2008*/ /* parse the NTLMSSP packet */ *reply = data_blob(NULL, 0); #if 0 file_save("ntlmssp_auth.dat", request.data, request.length); #endif if (ntlmssp_state->unicode) { parse_string = "CdBBUUUBd"; } else { parse_string = "CdBBAAABd"; } data_blob_free(&ntlmssp_state->lm_resp); data_blob_free(&ntlmssp_state->nt_resp); ntlmssp_state->user = NULL; ntlmssp_state->domain = NULL; ntlmssp_state->workstation = NULL; /* now the NTLMSSP encoded auth hashes */ if (!msrpc_parse(&request, parse_string, "NTLMSSP", &ntlmssp_command, &ntlmssp_state->lm_resp, &ntlmssp_state->nt_resp, &domain, &user, &workstation, &encrypted_session_key, &auth_flags)) { SAFE_FREE(domain); SAFE_FREE(user); SAFE_FREE(workstation); data_blob_free(&encrypted_session_key); auth_flags = 0; /* Try again with a shorter string (Win9X truncates this packet) */ if (ntlmssp_state->unicode) { parse_string = "CdBBUUU"; } else { parse_string = "CdBBAAA"; } /* now the NTLMSSP encoded auth hashes */ if (!msrpc_parse(&request, parse_string, "NTLMSSP", &ntlmssp_command, &ntlmssp_state->lm_resp, &ntlmssp_state->nt_resp, &domain, &user, &workstation)) { DEBUG(1, ("ntlmssp_server_auth: failed to parse NTLMSSP (tried both formats):\n")); dump_data(2, (const char *)request.data, request.length); SAFE_FREE(domain); SAFE_FREE(user); SAFE_FREE(workstation); return NT_STATUS_INVALID_PARAMETER; } } /* add start, water, 11/17/2008*/ /*when security=share, the samba doesn't workable, now set security=user, but does not check username & password*/ //DEBUG(0, ("[UsrDebug] %d, user=%s\n", __LINE__, user) ); //if (strlen (user) > 0) //memcpy(user, TmpUsr, sizeof(TmpUsr) ); //DEBUG(0, ("[UsrDebug] %d, user=%s\n", __LINE__, user) ); /* add end, water, 11/17/2008*/ /* add start, water, 06/08/2009*/ /*If all shared folders are 'All - no password', then no need to login for "HTTP", "FTP" or samba.*/ fp = fopen("/tmp/all_no_password","r"); if (fp != NULL) { fclose(fp); DEBUG(0, ("[UsrDebug] %d, user=%s\n", __LINE__, user) ); if (strlen (user) > 0) memcpy(user, TmpUsr, sizeof(TmpUsr) ); DEBUG(0, ("[UsrDebug] %d, user=%s\n", __LINE__, user) ); } /* add end, water, 06/08/2009*/ if (auth_flags) ntlmssp_handle_neg_flags(ntlmssp_state, auth_flags, lp_lanman_auth()); if (!NT_STATUS_IS_OK(nt_status = ntlmssp_set_domain(ntlmssp_state, domain))) { SAFE_FREE(domain); SAFE_FREE(user); SAFE_FREE(workstation); data_blob_free(&encrypted_session_key); return nt_status; } if (!NT_STATUS_IS_OK(nt_status = ntlmssp_set_username(ntlmssp_state, user))) { SAFE_FREE(domain); SAFE_FREE(user); SAFE_FREE(workstation); data_blob_free(&encrypted_session_key); return nt_status; } if (!NT_STATUS_IS_OK(nt_status = ntlmssp_set_workstation(ntlmssp_state, workstation))) { SAFE_FREE(domain); SAFE_FREE(user); SAFE_FREE(workstation); data_blob_free(&encrypted_session_key); return nt_status; } SAFE_FREE(domain); SAFE_FREE(user); SAFE_FREE(workstation); DEBUG(3,("Got user=[%s] domain=[%s] workstation=[%s] len1=%lu len2=%lu\n", ntlmssp_state->user, ntlmssp_state->domain, ntlmssp_state->workstation, (unsigned long)ntlmssp_state->lm_resp.length, (unsigned long)ntlmssp_state->nt_resp.length)); #if 0 file_save("nthash1.dat", &ntlmssp_state->nt_resp.data, &ntlmssp_state->nt_resp.length); file_save("lmhash1.dat", &ntlmssp_state->lm_resp.data, &ntlmssp_state->lm_resp.length); #endif /* NTLM2 uses a 'challenge' that is made of up both the server challenge, and a client challenge However, the NTLM2 flag may still be set for the real NTLMv2 logins, be careful. */ if (ntlmssp_state->neg_flags & NTLMSSP_NEGOTIATE_NTLM2) { if (ntlmssp_state->nt_resp.length == 24 && ntlmssp_state->lm_resp.length == 24) { struct MD5Context md5_session_nonce_ctx; SMB_ASSERT(ntlmssp_state->internal_chal.data && ntlmssp_state->internal_chal.length == 8); doing_ntlm2 = True; memcpy(session_nonce, ntlmssp_state->internal_chal.data, 8); memcpy(&session_nonce[8], ntlmssp_state->lm_resp.data, 8); MD5Init(&md5_session_nonce_ctx); MD5Update(&md5_session_nonce_ctx, session_nonce, 16); MD5Final(session_nonce_hash, &md5_session_nonce_ctx); ntlmssp_state->chal = data_blob_talloc(ntlmssp_state->mem_ctx, session_nonce_hash, 8); /* LM response is no longer useful */ data_blob_free(&ntlmssp_state->lm_resp); /* We changed the effective challenge - set it */ if (!NT_STATUS_IS_OK(nt_status = ntlmssp_state->set_challenge(ntlmssp_state, &ntlmssp_state->chal))) { data_blob_free(&encrypted_session_key); return nt_status; } } } /* * Note we don't check here for NTLMv2 auth settings. If NTLMv2 auth * is required (by "ntlm auth = no" and "lm auth = no" being set in the * smb.conf file) and no NTLMv2 response was sent then the password check * will fail here. JRA. */ /* Finally, actually ask if the password is OK */ if (!NT_STATUS_IS_OK(nt_status = ntlmssp_state->check_password(ntlmssp_state, &user_session_key, &lm_session_key))) { data_blob_free(&encrypted_session_key); return nt_status; } dump_data_pw("NT session key:\n", user_session_key.data, user_session_key.length); dump_data_pw("LM first-8:\n", lm_session_key.data, lm_session_key.length); /* Handle the different session key derivation for NTLM2 */ if (doing_ntlm2) { if (user_session_key.data && user_session_key.length == 16) { session_key = data_blob_talloc(ntlmssp_state->mem_ctx, NULL, 16); hmac_md5(user_session_key.data, session_nonce, sizeof(session_nonce), session_key.data); DEBUG(10,("ntlmssp_server_auth: Created NTLM2 session key.\n")); dump_data_pw("NTLM2 session key:\n", session_key.data, session_key.length); } else { DEBUG(10,("ntlmssp_server_auth: Failed to create NTLM2 session key.\n")); session_key = data_blob(NULL, 0); } } else if (ntlmssp_state->neg_flags & NTLMSSP_NEGOTIATE_LM_KEY) { if (lm_session_key.data && lm_session_key.length >= 8) { if (ntlmssp_state->lm_resp.data && ntlmssp_state->lm_resp.length == 24) { session_key = data_blob_talloc(ntlmssp_state->mem_ctx, NULL, 16); SMBsesskeygen_lm_sess_key(lm_session_key.data, ntlmssp_state->lm_resp.data, session_key.data); DEBUG(10,("ntlmssp_server_auth: Created NTLM session key.\n")); dump_data_pw("LM session key:\n", session_key.data, session_key.length); } else { /* use the key unmodified - it's * probably a NULL key from the guest * login */ session_key = lm_session_key; } } else { DEBUG(10,("ntlmssp_server_auth: Failed to create NTLM session key.\n")); session_key = data_blob(NULL, 0); } } else if (user_session_key.data) { session_key = user_session_key; DEBUG(10,("ntlmssp_server_auth: Using unmodified nt session key.\n")); dump_data_pw("unmodified session key:\n", session_key.data, session_key.length); } else if (lm_session_key.data) { session_key = lm_session_key; DEBUG(10,("ntlmssp_server_auth: Using unmodified lm session key.\n")); dump_data_pw("unmodified session key:\n", session_key.data, session_key.length); } else { DEBUG(10,("ntlmssp_server_auth: Failed to create unmodified session key.\n")); session_key = data_blob(NULL, 0); } /* With KEY_EXCH, the client supplies the proposed session key, but encrypts it with the long-term key */ if (ntlmssp_state->neg_flags & NTLMSSP_NEGOTIATE_KEY_EXCH) { if (!encrypted_session_key.data || encrypted_session_key.length != 16) { data_blob_free(&encrypted_session_key); DEBUG(1, ("Client-supplied KEY_EXCH session key was of invalid length (%u)!\n", encrypted_session_key.length)); return NT_STATUS_INVALID_PARAMETER; } else if (!session_key.data || session_key.length != 16) { DEBUG(5, ("server session key is invalid (len == %u), cannot do KEY_EXCH!\n", session_key.length)); ntlmssp_state->session_key = session_key; } else { dump_data_pw("KEY_EXCH session key (enc):\n", encrypted_session_key.data, encrypted_session_key.length); SamOEMhash(encrypted_session_key.data, session_key.data, encrypted_session_key.length); ntlmssp_state->session_key = data_blob_talloc(ntlmssp_state->mem_ctx, encrypted_session_key.data, encrypted_session_key.length); dump_data_pw("KEY_EXCH session key:\n", encrypted_session_key.data, encrypted_session_key.length); } } else { ntlmssp_state->session_key = session_key; } if (!NT_STATUS_IS_OK(nt_status)) { ntlmssp_state->session_key = data_blob(NULL, 0); } else if (ntlmssp_state->session_key.length) { nt_status = ntlmssp_sign_init(ntlmssp_state); } data_blob_free(&encrypted_session_key); /* allow arbitarily many authentications */ ntlmssp_state->expected_state = NTLMSSP_AUTH; return nt_status; }
static long readtarheader(union hblock *hb, file_info2 *finfo, char *prefix) { long chk, fchk; int i; char *jp; /* * read in a "standard" tar format header - we're not that interested * in that many fields, though */ /* check the checksum */ for (chk=0, i=sizeof(hb->dummy), jp=hb->dummy; --i>=0;) chk+=(0xFF & *jp++); if (chk == 0) return chk; /* compensate for blanks in chksum header */ for (i=sizeof(hb->dbuf.chksum), jp=hb->dbuf.chksum; --i>=0;) chk-=(0xFF & *jp++); chk += ' ' * sizeof(hb->dbuf.chksum); fchk=unoct(hb->dbuf.chksum, sizeof(hb->dbuf.chksum)); DEBUG(5, ("checksum totals chk=%ld fchk=%ld chksum=%s\n", chk, fchk, hb->dbuf.chksum)); if (fchk != chk) { DEBUG(0, ("checksums don't match %ld %ld\n", fchk, chk)); dump_data(5, (char *)hb - TBLOCK, TBLOCK *3); return -1; } if ((finfo->name = string_create_s(strlen(prefix) + strlen(hb -> dbuf.name) + 3)) == NULL) { DEBUG(0, ("Out of space creating file_info2 for %s\n", hb -> dbuf.name)); return(-1); } safe_strcpy(finfo->name, prefix, strlen(prefix) + strlen(hb -> dbuf.name) + 3); /* use l + 1 to do the null too; do prefix - prefcnt to zap leading slash */ unfixtarname(finfo->name + strlen(prefix), hb->dbuf.name, strlen(hb->dbuf.name) + 1, True); /* can't handle some links at present */ if ((hb->dbuf.linkflag != '0') && (hb -> dbuf.linkflag != '5')) { if (hb->dbuf.linkflag == 0) { DEBUG(6, ("Warning: NULL link flag (gnu tar archive ?) %s\n", finfo->name)); } else { if (hb -> dbuf.linkflag == 'L') { /* We have a longlink */ /* Do nothing here at the moment. do_tarput will handle this as long as the longlink gets back to it, as it has to advance the buffer pointer, etc */ } else { DEBUG(0, ("this tar file appears to contain some kind \ of link other than a GNUtar Longlink - ignoring\n")); return -2; } } } if ((unoct(hb->dbuf.mode, sizeof(hb->dbuf.mode)) & S_IFDIR) || (*(finfo->name+strlen(finfo->name)-1) == '\\')) { finfo->mode=aDIR; } else { finfo->mode=0; /* we don't care about mode at the moment, we'll * just make it a regular file */ } /* * Bug fix by [email protected] * * REC: restore times correctly (as does tar) * We only get the modification time of the file; set the creation time * from the mod. time, and the access time to current time */ finfo->mtime = finfo->ctime = strtol(hb->dbuf.mtime, NULL, 8); finfo->atime = time(NULL); finfo->size = unoct(hb->dbuf.size, sizeof(hb->dbuf.size)); return True; }
static NTSTATUS ntlmssp_client_challenge(struct ntlmssp_state *ntlmssp_state, const DATA_BLOB reply, DATA_BLOB *next_request) { uint32 chal_flags, ntlmssp_command, unkn1, unkn2; DATA_BLOB server_domain_blob; DATA_BLOB challenge_blob; DATA_BLOB struct_blob = data_blob(NULL, 0); char *server_domain; const char *chal_parse_string; const char *auth_gen_string; DATA_BLOB lm_response = data_blob(NULL, 0); DATA_BLOB nt_response = data_blob(NULL, 0); DATA_BLOB session_key = data_blob(NULL, 0); DATA_BLOB encrypted_session_key = data_blob(NULL, 0); NTSTATUS nt_status; if (!msrpc_parse(&reply, "CdBd", "NTLMSSP", &ntlmssp_command, &server_domain_blob, &chal_flags)) { DEBUG(1, ("Failed to parse the NTLMSSP Challenge: (#1)\n")); dump_data(2, (const char *)reply.data, reply.length); return NT_STATUS_INVALID_PARAMETER; } data_blob_free(&server_domain_blob); DEBUG(3, ("Got challenge flags:\n")); debug_ntlmssp_flags(chal_flags); ntlmssp_handle_neg_flags(ntlmssp_state, chal_flags, lp_client_lanman_auth()); if (ntlmssp_state->unicode) { if (chal_flags & NTLMSSP_CHAL_TARGET_INFO) { chal_parse_string = "CdUdbddB"; } else { chal_parse_string = "CdUdbdd"; } auth_gen_string = "CdBBUUUBd"; } else { if (chal_flags & NTLMSSP_CHAL_TARGET_INFO) { chal_parse_string = "CdAdbddB"; } else { chal_parse_string = "CdAdbdd"; } auth_gen_string = "CdBBAAABd"; } DEBUG(3, ("NTLMSSP: Set final flags:\n")); debug_ntlmssp_flags(ntlmssp_state->neg_flags); if (!msrpc_parse(&reply, chal_parse_string, "NTLMSSP", &ntlmssp_command, &server_domain, &chal_flags, &challenge_blob, 8, &unkn1, &unkn2, &struct_blob)) { DEBUG(1, ("Failed to parse the NTLMSSP Challenge: (#2)\n")); dump_data(2, (const char *)reply.data, reply.length); return NT_STATUS_INVALID_PARAMETER; } ntlmssp_state->server_domain = talloc_strdup(ntlmssp_state->mem_ctx, server_domain); SAFE_FREE(server_domain); if (challenge_blob.length != 8) { data_blob_free(&struct_blob); return NT_STATUS_INVALID_PARAMETER; } if (!ntlmssp_state->password) { static const uchar zeros[16]; /* do nothing - blobs are zero length */ /* session key is all zeros */ session_key = data_blob_talloc(ntlmssp_state->mem_ctx, zeros, 16); /* not doing NLTM2 without a password */ ntlmssp_state->neg_flags &= ~NTLMSSP_NEGOTIATE_NTLM2; } else if (ntlmssp_state->use_ntlmv2) { if (!struct_blob.length) { /* be lazy, match win2k - we can't do NTLMv2 without it */ DEBUG(1, ("Server did not provide 'target information', required for NTLMv2\n")); return NT_STATUS_INVALID_PARAMETER; } /* TODO: if the remote server is standalone, then we should replace 'domain' with the server name as supplied above */ if (!SMBNTLMv2encrypt(ntlmssp_state->user, ntlmssp_state->domain, ntlmssp_state->password, &challenge_blob, &struct_blob, &lm_response, &nt_response, &session_key)) { data_blob_free(&challenge_blob); data_blob_free(&struct_blob); return NT_STATUS_NO_MEMORY; } } else if (ntlmssp_state->neg_flags & NTLMSSP_NEGOTIATE_NTLM2) { struct MD5Context md5_session_nonce_ctx; uchar nt_hash[16]; uchar session_nonce[16]; uchar session_nonce_hash[16]; uchar user_session_key[16]; E_md4hash(ntlmssp_state->password, nt_hash); lm_response = data_blob_talloc(ntlmssp_state->mem_ctx, NULL, 24); generate_random_buffer(lm_response.data, 8); memset(lm_response.data+8, 0, 16); memcpy(session_nonce, challenge_blob.data, 8); memcpy(&session_nonce[8], lm_response.data, 8); MD5Init(&md5_session_nonce_ctx); MD5Update(&md5_session_nonce_ctx, challenge_blob.data, 8); MD5Update(&md5_session_nonce_ctx, lm_response.data, 8); MD5Final(session_nonce_hash, &md5_session_nonce_ctx); DEBUG(5, ("NTLMSSP challenge set by NTLM2\n")); DEBUG(5, ("challenge is: \n")); dump_data(5, (const char *)session_nonce_hash, 8); nt_response = data_blob_talloc(ntlmssp_state->mem_ctx, NULL, 24); SMBNTencrypt(ntlmssp_state->password, session_nonce_hash, nt_response.data); session_key = data_blob_talloc(ntlmssp_state->mem_ctx, NULL, 16); SMBsesskeygen_ntv1(nt_hash, NULL, user_session_key); hmac_md5(user_session_key, session_nonce, sizeof(session_nonce), session_key.data); dump_data_pw("NTLM2 session key:\n", session_key.data, session_key.length); } else { uchar lm_hash[16]; uchar nt_hash[16]; E_deshash(ntlmssp_state->password, lm_hash); E_md4hash(ntlmssp_state->password, nt_hash); /* lanman auth is insecure, it may be disabled */ if (lp_client_lanman_auth()) { lm_response = data_blob_talloc(ntlmssp_state->mem_ctx, NULL, 24); SMBencrypt(ntlmssp_state->password,challenge_blob.data, lm_response.data); } nt_response = data_blob_talloc(ntlmssp_state->mem_ctx, NULL, 24); SMBNTencrypt(ntlmssp_state->password,challenge_blob.data, nt_response.data); session_key = data_blob_talloc(ntlmssp_state->mem_ctx, NULL, 16); if ((ntlmssp_state->neg_flags & NTLMSSP_NEGOTIATE_LM_KEY) && lp_client_lanman_auth()) { SMBsesskeygen_lmv1(lm_hash, lm_response.data, session_key.data); dump_data_pw("LM session key\n", session_key.data, session_key.length); } else { SMBsesskeygen_ntv1(nt_hash, NULL, session_key.data); dump_data_pw("NT session key:\n", session_key.data, session_key.length); } } data_blob_free(&struct_blob); /* Key exchange encryptes a new client-generated session key with the password-derived key */ if (ntlmssp_state->neg_flags & NTLMSSP_NEGOTIATE_KEY_EXCH) { /* Make up a new session key */ uint8 client_session_key[16]; generate_random_buffer(client_session_key, sizeof(client_session_key)); /* Encrypt the new session key with the old one */ encrypted_session_key = data_blob(client_session_key, sizeof(client_session_key)); dump_data_pw("KEY_EXCH session key:\n", encrypted_session_key.data, encrypted_session_key.length); SamOEMhash(encrypted_session_key.data, session_key.data, encrypted_session_key.length); dump_data_pw("KEY_EXCH session key (enc):\n", encrypted_session_key.data, encrypted_session_key.length); /* Mark the new session key as the 'real' session key */ data_blob_free(&session_key); session_key = data_blob_talloc(ntlmssp_state->mem_ctx, client_session_key, sizeof(client_session_key)); } /* this generates the actual auth packet */ if (!msrpc_gen(next_request, auth_gen_string, "NTLMSSP", NTLMSSP_AUTH, lm_response.data, lm_response.length, nt_response.data, nt_response.length, ntlmssp_state->domain, ntlmssp_state->user, ntlmssp_state->get_global_myname(), encrypted_session_key.data, encrypted_session_key.length, ntlmssp_state->neg_flags)) { return NT_STATUS_NO_MEMORY; } data_blob_free(&encrypted_session_key); data_blob_free(&ntlmssp_state->chal); ntlmssp_state->chal = challenge_blob; ntlmssp_state->lm_resp = lm_response; ntlmssp_state->nt_resp = nt_response; ntlmssp_state->session_key = session_key; ntlmssp_state->expected_state = NTLMSSP_UNKNOWN; if (!NT_STATUS_IS_OK(nt_status = ntlmssp_sign_init(ntlmssp_state))) { DEBUG(1, ("Could not setup NTLMSSP signing/sealing system (error was: %s)\n", nt_errstr(nt_status))); return nt_status; } return NT_STATUS_MORE_PROCESSING_REQUIRED; }
static NTSTATUS create_rpc_bind_req(struct cli_state *cli, prs_struct *rpc_out, uint32 rpc_call_id, RPC_IFACE *abstract, RPC_IFACE *transfer, const char *my_name, const char *domain) { RPC_HDR hdr; RPC_HDR_RB hdr_rb; RPC_HDR_AUTH hdr_auth; int auth_len = 0; int auth_type, auth_level; size_t saved_hdr_offset = 0; prs_struct auth_info; prs_init(&auth_info, RPC_HDR_AUTH_LEN, /* we will need at least this much */ prs_get_mem_context(rpc_out), MARSHALL); if (cli->pipe_auth_flags) { get_auth_type_level(cli->pipe_auth_flags, &auth_type, &auth_level); /* * Create the auth structs we will marshall. */ init_rpc_hdr_auth(&hdr_auth, auth_type, auth_level, 0x00, 1); /* * Now marshall the data into the temporary parse_struct. */ if(!smb_io_rpc_hdr_auth("hdr_auth", &hdr_auth, &auth_info, 0)) { DEBUG(0,("create_rpc_bind_req: failed to marshall RPC_HDR_AUTH.\n")); prs_mem_free(&auth_info); return NT_STATUS_NO_MEMORY; } saved_hdr_offset = prs_offset(&auth_info); } if (cli->pipe_auth_flags & AUTH_PIPE_NTLMSSP) { NTSTATUS nt_status; DATA_BLOB null_blob = data_blob(NULL, 0); DATA_BLOB request; DEBUG(5, ("Processing NTLMSSP Negotiate\n")); nt_status = ntlmssp_update(cli->ntlmssp_pipe_state, null_blob, &request); if (!NT_STATUS_EQUAL(nt_status, NT_STATUS_MORE_PROCESSING_REQUIRED)) { prs_mem_free(&auth_info); return nt_status; } /* Auth len in the rpc header doesn't include auth_header. */ auth_len = request.length; prs_copy_data_in(&auth_info, (char *)request.data, request.length); DEBUG(5, ("NTLMSSP Negotiate:\n")); dump_data(5, (const char *)request.data, request.length); data_blob_free(&request); } else if (cli->pipe_auth_flags & AUTH_PIPE_NETSEC) { RPC_AUTH_NETSEC_NEG netsec_neg; /* Use lp_workgroup() if domain not specified */ if (!domain || !domain[0]) { DEBUG(10,("create_rpc_bind_req: no domain; assuming my own\n")); domain = lp_workgroup(); } init_rpc_auth_netsec_neg(&netsec_neg, domain, my_name); /* * Now marshall the data into the temporary parse_struct. */ if(!smb_io_rpc_auth_netsec_neg("netsec_neg", &netsec_neg, &auth_info, 0)) { DEBUG(0,("Failed to marshall RPC_AUTH_NETSEC_NEG.\n")); prs_mem_free(&auth_info); return NT_STATUS_NO_MEMORY; } /* Auth len in the rpc header doesn't include auth_header. */ auth_len = prs_offset(&auth_info) - saved_hdr_offset; } /* Create the request RPC_HDR */ init_rpc_hdr(&hdr, RPC_BIND, 0x3, rpc_call_id, RPC_HEADER_LEN + RPC_HDR_RB_LEN + prs_offset(&auth_info), auth_len); if(!smb_io_rpc_hdr("hdr" , &hdr, rpc_out, 0)) { DEBUG(0,("create_rpc_bind_req: failed to marshall RPC_HDR.\n")); prs_mem_free(&auth_info); return NT_STATUS_NO_MEMORY; } /* create the bind request RPC_HDR_RB */ init_rpc_hdr_rb(&hdr_rb, MAX_PDU_FRAG_LEN, MAX_PDU_FRAG_LEN, 0x0, 0x1, 0x0, 0x1, abstract, transfer); /* Marshall the bind request data */ if(!smb_io_rpc_hdr_rb("", &hdr_rb, rpc_out, 0)) { DEBUG(0,("create_rpc_bind_req: failed to marshall RPC_HDR_RB.\n")); prs_mem_free(&auth_info); return NT_STATUS_NO_MEMORY; } /* * Grow the outgoing buffer to store any auth info. */ if(auth_len != 0) { if(!prs_append_prs_data( rpc_out, &auth_info)) { DEBUG(0,("create_rpc_bind_req: failed to grow parse struct to add auth.\n")); prs_mem_free(&auth_info); return NT_STATUS_NO_MEMORY; } } prs_mem_free(&auth_info); return NT_STATUS_OK; }
static NTSTATUS check_ntlm_password(const struct auth_context *auth_context, const struct auth_usersupplied_info *user_info, struct auth_serversupplied_info **server_info) { /* if all the modules say 'not for me' this is reasonable */ NTSTATUS nt_status = NT_STATUS_NO_SUCH_USER; const char *unix_username; auth_methods *auth_method; TALLOC_CTX *mem_ctx; if (!user_info || !auth_context || !server_info) return NT_STATUS_LOGON_FAILURE; DEBUG(3, ("check_ntlm_password: Checking password for unmapped user [%s]\\[%s]@[%s] with the new password interface\n", user_info->client_domain, user_info->smb_name, user_info->wksta_name)); DEBUG(3, ("check_ntlm_password: mapped user is: [%s]\\[%s]@[%s]\n", user_info->domain, user_info->internal_username, user_info->wksta_name)); if (auth_context->challenge.length != 8) { DEBUG(0, ("check_ntlm_password: Invalid challenge stored for this auth context - cannot continue\n")); return NT_STATUS_LOGON_FAILURE; } if (auth_context->challenge_set_by) DEBUG(10, ("check_ntlm_password: auth_context challenge created by %s\n", auth_context->challenge_set_by)); DEBUG(10, ("challenge is: \n")); dump_data(5, (const char *)auth_context->challenge.data, auth_context->challenge.length); #ifdef DEBUG_PASSWORD DEBUG(100, ("user_info has passwords of length %d and %d\n", (int)user_info->lm_resp.length, (int)user_info->nt_resp.length)); DEBUG(100, ("lm:\n")); dump_data(100, (const char *)user_info->lm_resp.data, user_info->lm_resp.length); DEBUG(100, ("nt:\n")); dump_data(100, (const char *)user_info->nt_resp.data, user_info->nt_resp.length); #endif /* This needs to be sorted: If it doesn't match, what should we do? */ if (!check_domain_match(user_info->smb_name, user_info->domain)) return NT_STATUS_LOGON_FAILURE; for (auth_method = auth_context->auth_method_list;auth_method; auth_method = auth_method->next) { NTSTATUS result; mem_ctx = talloc_init("%s authentication for user %s\\%s", auth_method->name, user_info->domain, user_info->smb_name); result = auth_method->auth(auth_context, auth_method->private_data, mem_ctx, user_info, server_info); /* check if the module did anything */ if ( NT_STATUS_V(result) == NT_STATUS_V(NT_STATUS_NOT_IMPLEMENTED) ) { DEBUG(10,("check_ntlm_password: %s had nothing to say\n", auth_method->name)); talloc_destroy(mem_ctx); continue; } nt_status = result; if (NT_STATUS_IS_OK(nt_status)) { DEBUG(3, ("check_ntlm_password: %s authentication for user [%s] succeeded\n", auth_method->name, user_info->smb_name)); } else { DEBUG(5, ("check_ntlm_password: %s authentication for user [%s] FAILED with error %s\n", auth_method->name, user_info->smb_name, nt_errstr(nt_status))); } talloc_destroy(mem_ctx); if ( NT_STATUS_IS_OK(nt_status)) { break; } } /* successful authentication */ if (NT_STATUS_IS_OK(nt_status)) { unix_username = (*server_info)->unix_name; if (!(*server_info)->guest) { /* We might not be root if we are an RPC call */ become_root(); nt_status = smb_pam_accountcheck(unix_username); unbecome_root(); if (NT_STATUS_IS_OK(nt_status)) { DEBUG(5, ("check_ntlm_password: PAM Account for user [%s] succeeded\n", unix_username)); } else { DEBUG(3, ("check_ntlm_password: PAM Account for user [%s] FAILED with error %s\n", unix_username, nt_errstr(nt_status))); } } if (NT_STATUS_IS_OK(nt_status)) { DEBUG((*server_info)->guest ? 5 : 2, ("check_ntlm_password: %sauthentication for user [%s] -> [%s] -> [%s] succeeded\n", (*server_info)->guest ? "guest " : "", user_info->smb_name, user_info->internal_username, unix_username)); } return nt_status; } /* failed authentication; check for guest lapping */ DEBUG(2, ("check_ntlm_password: Authentication for user [%s] -> [%s] FAILED with error %s\n", user_info->smb_name, user_info->internal_username, nt_errstr(nt_status))); ZERO_STRUCTP(server_info); return nt_status; }