static int extended_dn_read_SID(struct ldb_context *ldb, void *mem_ctx, const struct ldb_val *in, struct ldb_val *out) { struct dom_sid sid; enum ndr_err_code ndr_err; if (ldif_comparision_objectSid_isString(in)) { if (ldif_read_objectSid(ldb, mem_ctx, in, out) == 0) { return 0; } } /* Perhaps not a string after all */ *out = data_blob_talloc(mem_ctx, NULL, in->length/2+1); if (!out->data) { return -1; } (*out).length = strhex_to_str((char *)out->data, out->length, (const char *)in->data, in->length); /* Check it looks like a SID */ ndr_err = ndr_pull_struct_blob_all(out, mem_ctx, &sid, (ndr_pull_flags_fn_t)ndr_pull_dom_sid); if (!NDR_ERR_CODE_IS_SUCCESS(ndr_err)) { return -1; } return 0; }
static int extended_dn_read_GUID(struct ldb_context *ldb, void *mem_ctx, const struct ldb_val *in, struct ldb_val *out) { struct GUID guid; NTSTATUS status; if (in->length == 36 && ldif_read_objectGUID(ldb, mem_ctx, in, out) == 0) { return 0; } /* Try as 'hex' form */ if (in->length != 32) { return -1; } *out = data_blob_talloc(mem_ctx, NULL, in->length/2+1); if (!out->data) { return -1; } (*out).length = strhex_to_str((char *)out->data, out->length, (const char *)in->data, in->length); /* Check it looks like a GUID */ status = GUID_from_ndr_blob(out, &guid); if (!NT_STATUS_IS_OK(status)) { data_blob_free(out); return -1; } return 0; }
NTSTATUS ntlmssp_set_password_hash(struct ntlmssp_state *state, const char *pwhash) { char nt_hash[16]; size_t converted; converted = strhex_to_str( nt_hash, sizeof(nt_hash), pwhash, strlen(pwhash)); if (converted != sizeof(nt_hash)) { return NT_STATUS_INVALID_PARAMETER; } TALLOC_FREE(state->lm_hash); TALLOC_FREE(state->nt_hash); state->nt_hash = (uint8_t *)talloc_memdup(state, nt_hash, 16); if (!state->nt_hash) { return NT_STATUS_NO_MEMORY; } return NT_STATUS_OK; }
struct dsdb_dn *dsdb_dn_parse(TALLOC_CTX *mem_ctx, struct ldb_context *ldb, const struct ldb_val *dn_blob, const char *dn_oid) { struct dsdb_dn *dsdb_dn; struct ldb_dn *dn; const char *data; size_t len; TALLOC_CTX *tmp_ctx; char *p1; char *p2; uint32_t blen; struct ldb_val bval; struct ldb_val dval; char *dn_str; enum dsdb_dn_format dn_format = dsdb_dn_oid_to_format(dn_oid); switch (dn_format) { case DSDB_INVALID_DN: return NULL; case DSDB_NORMAL_DN: { dn = ldb_dn_from_ldb_val(mem_ctx, ldb, dn_blob); if (!dn || !ldb_dn_validate(dn)) { talloc_free(dn); return NULL; } return dsdb_dn_construct_internal(mem_ctx, dn, data_blob_null, dn_format, dn_oid); } case DSDB_BINARY_DN: if (dn_blob->length < 2 || dn_blob->data[0] != 'B' || dn_blob->data[1] != ':') { return NULL; } break; case DSDB_STRING_DN: if (dn_blob->length < 2 || dn_blob->data[0] != 'S' || dn_blob->data[1] != ':') { return NULL; } break; default: return NULL; } if (dn_blob && dn_blob->data && (strlen((const char*)dn_blob->data) != dn_blob->length)) { /* The RDN must not contain a character with value 0x0 */ return NULL; } if (!dn_blob->data || dn_blob->length == 0) { return NULL; } tmp_ctx = talloc_new(mem_ctx); if (tmp_ctx == NULL) { return NULL; } data = (const char *)dn_blob->data; len = dn_blob->length - 2; p1 = talloc_strndup(tmp_ctx, (const char *)dn_blob->data + 2, len); if (!p1) { goto failed; } errno = 0; blen = strtoul(p1, &p2, 10); if (errno != 0) { DEBUG(10, (__location__ ": failed\n")); goto failed; } if (p2 == NULL) { DEBUG(10, (__location__ ": failed\n")); goto failed; } if (p2[0] != ':') { DEBUG(10, (__location__ ": failed\n")); goto failed; } len -= PTR_DIFF(p2,p1);//??? p1 = p2+1; len--; if (blen >= len) { DEBUG(10, (__location__ ": blen=%u len=%u\n", (unsigned)blen, (unsigned)len)); goto failed; } p2 = p1 + blen; if (p2[0] != ':') { DEBUG(10, (__location__ ": %s", p2)); goto failed; } dn_str = p2+1; switch (dn_format) { case DSDB_BINARY_DN: if ((blen % 2 != 0)) { DEBUG(10, (__location__ ": blen=%u - not an even number\n", (unsigned)blen)); goto failed; } if (blen >= 2) { bval.length = (blen/2)+1; bval.data = talloc_size(tmp_ctx, bval.length); if (bval.data == NULL) { DEBUG(10, (__location__ ": err\n")); goto failed; } bval.data[bval.length-1] = 0; bval.length = strhex_to_str((char *)bval.data, bval.length, p1, blen); if (bval.length != (blen / 2)) { DEBUG(10, (__location__ ": non hexidecimal characters found in binary prefix\n")); goto failed; } } else { bval = data_blob_null; } break; case DSDB_STRING_DN: bval = data_blob(p1, blen); break; default: /* never reached */ return NULL; } dval.data = (uint8_t *)dn_str; dval.length = strlen(dn_str); dn = ldb_dn_from_ldb_val(tmp_ctx, ldb, &dval); if (!dn || !ldb_dn_validate(dn)) { DEBUG(10, (__location__ ": err\n")); goto failed; } dsdb_dn = dsdb_dn_construct(mem_ctx, dn, bval, dn_oid); return dsdb_dn; failed: talloc_free(tmp_ctx); return NULL; }
/** build a GUID from a string */ _PUBLIC_ NTSTATUS GUID_from_data_blob(const DATA_BLOB *s, struct GUID *guid) { NTSTATUS status = NT_STATUS_INVALID_PARAMETER; uint32_t time_low; uint32_t time_mid, time_hi_and_version; uint32_t clock_seq[2]; uint32_t node[6]; uint8_t buf16[16]; DATA_BLOB blob16 = data_blob_const(buf16, sizeof(buf16)); int i; if (s->data == NULL) { return NT_STATUS_INVALID_PARAMETER; } if (s->length == 36) { TALLOC_CTX *mem_ctx; const char *string; mem_ctx = talloc_new(NULL); NT_STATUS_HAVE_NO_MEMORY(mem_ctx); string = talloc_strndup(mem_ctx, (const char *)s->data, s->length); NT_STATUS_HAVE_NO_MEMORY(string); if (11 == sscanf(string, "%08x-%04x-%04x-%02x%02x-%02x%02x%02x%02x%02x%02x", &time_low, &time_mid, &time_hi_and_version, &clock_seq[0], &clock_seq[1], &node[0], &node[1], &node[2], &node[3], &node[4], &node[5])) { status = NT_STATUS_OK; } talloc_free(mem_ctx); } else if (s->length == 38) { TALLOC_CTX *mem_ctx; const char *string; mem_ctx = talloc_new(NULL); NT_STATUS_HAVE_NO_MEMORY(mem_ctx); string = talloc_strndup(mem_ctx, (const char *)s->data, s->length); NT_STATUS_HAVE_NO_MEMORY(string); if (11 == sscanf((const char *)s->data, "{%08x-%04x-%04x-%02x%02x-%02x%02x%02x%02x%02x%02x}", &time_low, &time_mid, &time_hi_and_version, &clock_seq[0], &clock_seq[1], &node[0], &node[1], &node[2], &node[3], &node[4], &node[5])) { status = NT_STATUS_OK; } talloc_free(mem_ctx); } else if (s->length == 32) { size_t rlen = strhex_to_str((char *)blob16.data, blob16.length, (const char *)s->data, s->length); if (rlen == blob16.length) { /* goto the ndr_pull_struct_blob() path */ status = NT_STATUS_OK; s = &blob16; } } if (s->length == 16) { return GUID_from_ndr_blob(s, guid); } if (!NT_STATUS_IS_OK(status)) { return status; } guid->time_low = time_low; guid->time_mid = time_mid; guid->time_hi_and_version = time_hi_and_version; guid->clock_seq[0] = clock_seq[0]; guid->clock_seq[1] = clock_seq[1]; for (i=0;i<6;i++) { guid->node[i] = node[i]; } return NT_STATUS_OK; }
void init_rpc_blob_hex(RPC_DATA_BLOB *str, const char *buf) { ZERO_STRUCTP(str); str->buf_len = create_rpc_blob(str, strlen(buf)); str->buf_len = strhex_to_str((char *)str->buffer, str->buf_len, buf); }
/** \details Test the Compressed RTF decompression routine. This function: -# Loads some test data and checks it -# Decompresses the test data -# Checks that the decompressed data matches the expected result \param mt pointer on the top-level mapitest structure \return true on success, otherwise false */ _PUBLIC_ bool mapitest_noserver_lzfu(struct mapitest *mt) { enum MAPISTATUS retval; DATA_BLOB uncompressed1; DATA_BLOB uncompressed2; uint8_t compressed_hex[1024]; uint8_t *compressed; uint32_t compressed_length; compressed = talloc_array(mt->mem_ctx, uint8_t, 1024); memcpy(compressed_hex, RTF_COMPRESSED1_HEX, 98); compressed_length = strhex_to_str((char*)compressed, 1024, (char*)compressed_hex, 98); if (compressed_length != 49) { mapitest_print(mt, "* %-40s: uncompress RTF - Bad length\n", "LZFU"); return false; } uint32_t crc = calculateCRC(compressed, 0x10, (49-0x10)); if (crc == 0xA7C7C5F1) { mapitest_print(mt, "* CRC pass\n"); } else { mapitest_print(mt, "* CRC failure, expected 0xA7C7C5F1, but got 0x%08X\n", crc); } retval = uncompress_rtf(mt->mem_ctx, compressed, compressed_length, &uncompressed1); if (retval != MAPI_E_SUCCESS) { mapitest_print_retval(mt, "uncompress_rtf - step 1 (bad retval)"); return false; } if (sizeof(RTF_UNCOMPRESSED1) != uncompressed1.length) { mapitest_print(mt, "* %-40s: FAILED (bad length: %i vs %i)\n", "uncompress_rtf - step 1", sizeof(RTF_UNCOMPRESSED1), uncompressed1.length); return false; } if (!strncmp((char*)uncompressed1.data, RTF_UNCOMPRESSED1, uncompressed1.length)) { mapitest_print(mt, "* %-40s: PASSED\n", "uncompress_rtf - step 1"); } else { mapitest_print(mt, "* %-40s: FAILED - %s\n", "uncompress_rtf - step 1", (char*)uncompressed1.data); return false; } memcpy(compressed_hex, RTF_COMPRESSED2_HEX, 60); compressed_length = strhex_to_str((char*)compressed, 1024, (char*)compressed_hex, 60); if (compressed_length != 30) { mapitest_print(mt, "* %-40s: uncompress RTF - Bad length\n", "LZFU"); return false; } retval = uncompress_rtf(mt->mem_ctx, compressed, compressed_length, &uncompressed2); if (retval != MAPI_E_SUCCESS) { mapitest_print_retval(mt, "uncompress_rtf - step 2 (bad retval)"); return false; } if (!strncmp((char*)uncompressed2.data, RTF_UNCOMPRESSED2, uncompressed2.length)) { mapitest_print(mt, "* %-40s: PASSED\n", "uncompress_rtf - step 2"); } else { mapitest_print(mt, "* %-40s: FAILED - %s\n", "uncompress_rtf - step 2", (char*)uncompressed2.data); return false; } /* TODO: add an uncompressed test here */ return true; }
static bool mapitest_noserver_srowset_tagged(struct mapitest *mt) { enum MAPISTATUS retval; struct loadparm_context *lp_ctx = NULL; DATA_BLOB rawData; uint8_t rawDataHex[1024]; struct SRowSet rowSet; struct SRowSet referenceRowSet; struct SPropTagArray *proptags; uint32_t rowNum; retval = GetLoadparmContext(mt->mapi_ctx, &lp_ctx); if (retval != MAPI_E_SUCCESS) return false; rawData.data = talloc_array(mt->mem_ctx, uint8_t, 1024); memcpy(rawDataHex, SROWSET_TAGGED, 2*SROWSET_TAGGED_LEN); rawData.length = strhex_to_str((char*)rawData.data, 1024, (char*)rawDataHex, 2*SROWSET_TAGGED_LEN); if (rawData.length != SROWSET_TAGGED_LEN) { mapitest_print(mt, "* %-40s: tagged - Bad length\n", "SRowSet"); return false; } proptags = set_SPropTagArray(mt->mem_ctx, 2, PR_SENDER_NAME, PR_BODY); rowSet.cRows = 16; rowSet.aRow = talloc_array(mt->mem_ctx, struct SRow, 16); emsmdb_get_SRowSet(mt->mem_ctx, &rowSet, proptags, &rawData); /* Check the resulting SRowSet */ if (rowSet.cRows != 16) { mapitest_print(mt, "* %-40s: unexpected row count: %i\n", "SRowSet", rowSet.cRows); return false; } /* Build reference RowSet */ referenceRowSet.cRows = rowSet.cRows; referenceRowSet.aRow = talloc_array(mt->mem_ctx, struct SRow, rowSet.cRows); for (rowNum = 0; rowNum < rowSet.cRows; ++rowNum) { referenceRowSet.aRow[rowNum].ulAdrEntryPad = 0; referenceRowSet.aRow[rowNum].cValues = 2; referenceRowSet.aRow[rowNum].lpProps = talloc_array(mt->mem_ctx, struct SPropValue, 2); referenceRowSet.aRow[rowNum].lpProps[0].ulPropTag = PR_SENDER_NAME; referenceRowSet.aRow[rowNum].lpProps[0].dwAlignPad = 0; referenceRowSet.aRow[rowNum].lpProps[1].ulPropTag = PR_BODY; referenceRowSet.aRow[rowNum].lpProps[1].dwAlignPad = 0; } referenceRowSet.aRow[0].lpProps[0].value.lpszA = "MT Dummy From"; referenceRowSet.aRow[0].lpProps[1].ulPropTag = PR_BODY_ERROR; referenceRowSet.aRow[0].lpProps[1].value.err = MAPI_E_NOT_FOUND; referenceRowSet.aRow[1].lpProps[0].value.lpszA = "MT Dummy From"; referenceRowSet.aRow[1].lpProps[1].value.lpszA = "Body of message 5"; referenceRowSet.aRow[2].lpProps[0].value.lpszA = "MT Dummy From"; referenceRowSet.aRow[2].lpProps[1].value.lpszA = "Body of message 6"; referenceRowSet.aRow[3].lpProps[0].value.lpszA = "MT Dummy From"; referenceRowSet.aRow[3].lpProps[1].value.lpszA = "Body of message 7"; referenceRowSet.aRow[4].lpProps[0].value.lpszA = "MT Dummy From"; referenceRowSet.aRow[4].lpProps[1].value.lpszA = "Body of message 8"; referenceRowSet.aRow[5].lpProps[0].value.lpszA = "MT Dummy From"; referenceRowSet.aRow[5].lpProps[1].value.lpszA = "Body of message 9"; referenceRowSet.aRow[6].lpProps[0].value.lpszA = "MT Dummy0"; referenceRowSet.aRow[6].lpProps[1].ulPropTag = PR_BODY_ERROR; referenceRowSet.aRow[6].lpProps[1].value.err = MAPI_E_NOT_FOUND; referenceRowSet.aRow[7].lpProps[0].value.lpszA = "MT Dummy0"; referenceRowSet.aRow[7].lpProps[1].value.lpszA = "Body of message 0"; referenceRowSet.aRow[8].lpProps[0].value.lpszA = "MT Dummy1"; referenceRowSet.aRow[8].lpProps[1].ulPropTag = PR_BODY_ERROR; referenceRowSet.aRow[8].lpProps[1].value.err = MAPI_E_NOT_FOUND; referenceRowSet.aRow[9].lpProps[0].value.lpszA = "MT Dummy1"; referenceRowSet.aRow[9].lpProps[1].value.lpszA = "Body of message 1"; referenceRowSet.aRow[10].lpProps[0].value.lpszA = "MT Dummy2"; referenceRowSet.aRow[10].lpProps[1].ulPropTag = PR_BODY_ERROR; referenceRowSet.aRow[10].lpProps[1].value.err = MAPI_E_NOT_FOUND; referenceRowSet.aRow[11].lpProps[0].value.lpszA = "MT Dummy2"; referenceRowSet.aRow[11].lpProps[1].value.lpszA = "Body of message 2"; referenceRowSet.aRow[12].lpProps[0].value.lpszA = "MT Dummy3"; referenceRowSet.aRow[12].lpProps[1].ulPropTag = PR_BODY_ERROR; referenceRowSet.aRow[12].lpProps[1].value.err = MAPI_E_NOT_FOUND; referenceRowSet.aRow[13].lpProps[0].value.lpszA = "MT Dummy3"; referenceRowSet.aRow[13].lpProps[1].value.lpszA = "Body of message 3"; referenceRowSet.aRow[14].lpProps[0].value.lpszA = "MT Dummy4"; referenceRowSet.aRow[14].lpProps[1].ulPropTag = PR_BODY_ERROR; referenceRowSet.aRow[14].lpProps[1].value.err = MAPI_E_NOT_FOUND; referenceRowSet.aRow[15].lpProps[0].value.lpszA = "MT Dummy4"; referenceRowSet.aRow[15].lpProps[1].value.lpszA = "Body of message 4"; /* compare result with reference rowset */ for (rowNum = 0; rowNum < rowSet.cRows; ++rowNum) { uint32_t i; /* check each row has expected number of properties */ if (rowSet.aRow[rowNum].cValues != referenceRowSet.aRow[rowNum].cValues) { mapitest_print(mt, "* %-40s: unexpected props count, row %i: %i\n", "SRowSet", rowSet.aRow[rowNum].cValues, rowNum); return false; } for (i=0; i < rowSet.aRow[rowNum].cValues; ++i) { /* check property tags are as expected */ if (rowSet.aRow[rowNum].lpProps[i].ulPropTag != referenceRowSet.aRow[rowNum].lpProps[i].ulPropTag) { mapitest_print(mt, "* %-40s: unexpected proptag (%i/%i): 0x%08x\n", "SRowSet", rowNum, i, rowSet.aRow[rowNum].lpProps[i].ulPropTag); return false; } /* check property values are as expected */ if ((rowSet.aRow[rowNum].lpProps[i].ulPropTag & 0xFFFF) == PT_ERROR) { if (rowSet.aRow[rowNum].lpProps[i].value.err != referenceRowSet.aRow[rowNum].lpProps[i].value.err) { mapitest_print(mt, "* %-40s: unexpected property error value (%i/%i): 0x%04x\n", "SRowSet", rowNum, i, rowSet.aRow[rowNum].lpProps[i].value.err); return false; } } else { if (strcmp(rowSet.aRow[rowNum].lpProps[i].value.lpszA, referenceRowSet.aRow[rowNum].lpProps[i].value.lpszA) != 0) { mapitest_print(mt, "* %-40s: unexpected property value (%i/%i): %s\n", "SRowSet", rowNum, i, rowSet.aRow[rowNum].lpProps[i].value.lpszA); return false; } } } } return true; }
DATA_BLOB hexstr_to_data_blob(TALLOC_CTX *mem_ctx, const char *string) { DATA_BLOB binary = data_blob_talloc(mem_ctx, NULL, strlen(string)/2); binary.length = strhex_to_str((char *)binary.data, binary.length, string, strlen(string)); return binary; }