size_t fixup_eventlog_record_tdb(struct eventlog_Record_tdb *r) { size_t size = 56; /* static size of integers before buffers start */ r->source_name_len = strlen_m_term(r->source_name) * 2; r->computer_name_len = strlen_m_term(r->computer_name) * 2; r->strings_len = ndr_size_string_array(r->strings, r->num_of_strings, LIBNDR_FLAG_STR_NULLTERM) * 2; /* fix up the eventlog entry structure as necessary */ r->sid_padding = ( ( 4 - ( ( r->source_name_len + r->computer_name_len ) % 4 ) ) % 4 ); r->padding = ( 4 - ( ( r->strings_len + r->data_length ) % 4 ) ) % 4; if (r->sid_length == 0) { /* Should not pad to a DWORD boundary for writing out the sid if there is no SID, so just propagate the padding to pad the data */ r->padding += r->sid_padding; r->sid_padding = 0; } size += r->source_name_len; size += r->computer_name_len; size += r->sid_padding; size += r->sid_length; size += r->strings_len; size += r->data_length; size += r->padding; /* need another copy of length at the end of the data */ size += sizeof(r->size); r->size = size; return size; }
NTSTATUS evlog_evt_entry_to_tdb_entry(TALLOC_CTX *mem_ctx, const struct EVENTLOGRECORD *e, struct eventlog_Record_tdb *t) { uint32_t i; ZERO_STRUCTP(t); t->size = e->Length; t->reserved = e->Reserved; t->record_number = e->RecordNumber; t->time_generated = e->TimeGenerated; t->time_written = e->TimeWritten; t->event_id = e->EventID; t->event_type = e->EventType; t->num_of_strings = e->NumStrings; t->event_category = e->EventCategory; t->reserved_flags = e->ReservedFlags; t->closing_record_number = e->ClosingRecordNumber; t->stringoffset = e->StringOffset; t->sid_length = e->UserSidLength; t->sid_offset = e->UserSidOffset; t->data_length = e->DataLength; t->data_offset = e->DataOffset; t->source_name_len = 2 * strlen_m_term(e->SourceName); t->source_name = talloc_strdup(mem_ctx, e->SourceName); NT_STATUS_HAVE_NO_MEMORY(t->source_name); t->computer_name_len = 2 * strlen_m_term(e->Computername); t->computer_name = talloc_strdup(mem_ctx, e->Computername); NT_STATUS_HAVE_NO_MEMORY(t->computer_name); /* t->sid_padding; */ if (e->UserSidLength > 0) { const char *sid_str = NULL; smb_ucs2_t *dummy = NULL; sid_str = sid_string_talloc(mem_ctx, &e->UserSid); t->sid_length = rpcstr_push_talloc(mem_ctx, &dummy, sid_str); if (t->sid_length == -1) { return NT_STATUS_NO_MEMORY; } t->sid = data_blob_talloc(mem_ctx, (uint8_t *)dummy, t->sid_length); NT_STATUS_HAVE_NO_MEMORY(t->sid.data); } t->strings = talloc_array(mem_ctx, const char *, e->NumStrings); for (i=0; i < e->NumStrings; i++) { t->strings[i] = talloc_strdup(t->strings, e->Strings[i]); NT_STATUS_HAVE_NO_MEMORY(t->strings[i]); } t->strings_len = 2 * ndr_size_string_array(t->strings, t->num_of_strings, LIBNDR_FLAG_STR_NULLTERM); t->data = data_blob_talloc(mem_ctx, e->Data, e->DataLength); /* t->padding = r->Pad; */ return NT_STATUS_OK; }
static bool test_strlen_m_term(struct torture_context *tctx) { torture_assert_int_equal(tctx, strlen_m_term("foo"), 4, "simple len"); torture_assert_int_equal(tctx, strlen_m_term("foo\x83l"), 7, "extended len"); torture_assert_int_equal(tctx, strlen_m_term(""), 1, "empty"); torture_assert_int_equal(tctx, strlen_m_term(NULL), 0, "NULL"); return true; }
_PUBLIC_ enum ndr_err_code ndr_push_TRUSTED_DOM_PASS(struct ndr_push *ndr, int ndr_flags, const struct TRUSTED_DOM_PASS *r) { { uint32_t _flags_save_STRUCT = ndr->flags; ndr_set_flags(&ndr->flags, LIBNDR_FLAG_NOALIGN); if (ndr_flags & NDR_SCALARS) { NDR_CHECK(ndr_push_align(ndr, 4)); NDR_CHECK(ndr_push_uint32(ndr, NDR_SCALARS, strlen_m_term(r->uni_name))); NDR_CHECK(ndr_push_charset(ndr, NDR_SCALARS, r->uni_name, 32, sizeof(uint16_t), CH_UTF16)); NDR_CHECK(ndr_push_uint32(ndr, NDR_SCALARS, strlen(r->pass))); { uint32_t _flags_save_string = ndr->flags; ndr_set_flags(&ndr->flags, LIBNDR_FLAG_STR_ASCII|LIBNDR_FLAG_STR_NULLTERM); NDR_CHECK(ndr_push_string(ndr, NDR_SCALARS, r->pass)); ndr->flags = _flags_save_string; } NDR_CHECK(ndr_push_time_t(ndr, NDR_SCALARS, r->mod_time)); NDR_CHECK(ndr_push_dom_sid(ndr, NDR_SCALARS, &r->domain_sid)); NDR_CHECK(ndr_push_trailer_align(ndr, 4)); } if (ndr_flags & NDR_BUFFERS) { } ndr->flags = _flags_save_STRUCT; } return NDR_ERR_SUCCESS; }
/* winreg_EnumKey */ static WERROR dcesrv_winreg_EnumKey(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx, struct winreg_EnumKey *r) { struct dcesrv_handle *h; struct registry_key *key; const char *name, *classname; NTTIME last_mod; WERROR result; DCESRV_PULL_HANDLE_FAULT(h, r->in.handle, HTYPE_REGKEY); key = h->data; result = reg_key_get_subkey_by_index(mem_ctx, key, r->in.enum_index, &name, &classname, &last_mod); if (2*strlen_m_term(name) > r->in.name->size) { return WERR_MORE_DATA; } if (name != NULL) { r->out.name->name = name; r->out.name->length = 2*strlen_m_term(name); } else { r->out.name->name = r->in.name->name; r->out.name->length = r->in.name->length; } r->out.name->size = r->in.name->size; r->out.keyclass = r->in.keyclass; if (classname != NULL) { r->out.keyclass->name = classname; r->out.keyclass->length = 2*strlen_m_term(classname); } else { r->out.keyclass->name = r->in.keyclass->name; r->out.keyclass->length = r->in.keyclass->length; } r->out.keyclass->size = r->in.keyclass->size; if (r->in.last_changed_time != NULL) r->out.last_changed_time = &last_mod; return result; }
WERROR NetGetAnyDCName_r(struct libnetapi_ctx *ctx, struct NetGetAnyDCName *r) { NTSTATUS status; WERROR werr; struct dcerpc_binding_handle *b; const char *dcname; void *buffer; werr = libnetapi_get_binding_handle(ctx, r->in.server_name, &ndr_table_netlogon, &b); if (!W_ERROR_IS_OK(werr)) { goto done; } status = dcerpc_netr_GetAnyDCName(b, talloc_tos(), r->in.server_name, r->in.domain_name, &dcname, &werr); if (!NT_STATUS_IS_OK(status)) { werr = ntstatus_to_werror(status); goto done; } if (!W_ERROR_IS_OK(werr)) { goto done; } if (NetApiBufferAllocate(strlen_m_term(dcname), &buffer)) { werr = WERR_NOT_ENOUGH_MEMORY; goto done; } memcpy(buffer, dcname, strlen_m_term(dcname)); *r->out.buffer = buffer; done: return werr; }
_PUBLIC_ void ndr_print_TRUSTED_DOM_PASS(struct ndr_print *ndr, const char *name, const struct TRUSTED_DOM_PASS *r) { ndr_print_struct(ndr, name, "TRUSTED_DOM_PASS"); { uint32_t _flags_save_STRUCT = ndr->flags; ndr_set_flags(&ndr->flags, LIBNDR_FLAG_NOALIGN); ndr->depth++; ndr_print_uint32(ndr, "uni_name_len", (ndr->flags & LIBNDR_PRINT_SET_VALUES)?strlen_m_term(r->uni_name):r->uni_name_len); ndr_print_string(ndr, "uni_name", r->uni_name); ndr_print_uint32(ndr, "pass_len", (ndr->flags & LIBNDR_PRINT_SET_VALUES)?strlen(r->pass):r->pass_len); ndr_print_string(ndr, "pass", r->pass); ndr_print_time_t(ndr, "mod_time", r->mod_time); ndr_print_dom_sid(ndr, "domain_sid", &r->domain_sid); ndr->depth--; ndr->flags = _flags_save_STRUCT; } }
/* winreg_QueryInfoKey */ static WERROR dcesrv_winreg_QueryInfoKey(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx, struct winreg_QueryInfoKey *r) { struct dcesrv_handle *h; struct registry_key *key; const char *classname = NULL; WERROR result; DCESRV_PULL_HANDLE_FAULT(h, r->in.handle, HTYPE_REGKEY); key = h->data; switch (security_session_user_level(dce_call->conn->auth_state.session_info)) { case SECURITY_SYSTEM: case SECURITY_ADMINISTRATOR: case SECURITY_USER: result = reg_key_get_info(mem_ctx, key, &classname, r->out.num_subkeys, r->out.num_values, r->out.last_changed_time, r->out.max_subkeylen, r->out.max_valnamelen, r->out.max_valbufsize); if (classname != NULL) { r->out.classname->name = classname; r->out.classname->name_len = 2*strlen_m_term(classname); } else { r->out.classname->name = r->in.classname->name; r->out.classname->name_len = r->in.classname->name_len; } r->out.classname->name_size = r->in.classname->name_size; return result; default: return WERR_ACCESS_DENIED; } }
/* winreg_EnumValue */ static WERROR dcesrv_winreg_EnumValue(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx, struct winreg_EnumValue *r) { struct dcesrv_handle *h; struct registry_key *key; const char *data_name; uint32_t data_type; DATA_BLOB data; WERROR result; DCESRV_PULL_HANDLE_FAULT(h, r->in.handle, HTYPE_REGKEY); key = h->data; result = reg_key_get_value_by_index(mem_ctx, key, r->in.enum_index, &data_name, &data_type, &data); if (!W_ERROR_IS_OK(result)) { /* if the lookup wasn't successful, send client query back */ data_name = r->in.name->name; data_type = *r->in.type; data.data = r->in.value; data.length = *r->in.length; } /* check if there is enough room for the name */ if (r->in.name->size < 2*strlen_m_term(data_name)) { return WERR_MORE_DATA; } /* "data_name" is NULL when we query the default attribute */ if (data_name != NULL) { r->out.name->name = data_name; r->out.name->length = 2*strlen_m_term(data_name); } else { r->out.name->name = r->in.name->name; r->out.name->length = r->in.name->length; } r->out.name->size = r->in.name->size; r->out.type = talloc(mem_ctx, uint32_t); if (!r->out.type) { return WERR_NOMEM; } *r->out.type = data_type; /* check the client has enough room for the value */ if (r->in.value != NULL && r->in.size != NULL && data.length > *r->in.size) { return WERR_MORE_DATA; } if (r->in.value != NULL) { r->out.value = data.data; } if (r->in.size != NULL) { r->out.size = talloc(mem_ctx, uint32_t); *r->out.size = data.length; r->out.length = r->out.size; } return result; }
bool parse_logentry( TALLOC_CTX *mem_ctx, char *line, struct eventlog_Record_tdb *entry, bool * eor ) { char *start = NULL, *stop = NULL; start = line; /* empty line signyfiying record delimeter, or we're at the end of the buffer */ if ( start == NULL || strlen( start ) == 0 ) { DEBUG( 6, ( "parse_logentry: found end-of-record indicator.\n" ) ); *eor = True; return True; } if ( !( stop = strchr( line, ':' ) ) ) { return False; } DEBUG( 6, ( "parse_logentry: trying to parse [%s].\n", line ) ); if ( 0 == strncmp( start, "LEN", stop - start ) ) { /* This will get recomputed later anyway -- probably not necessary */ entry->size = atoi( stop + 1 ); } else if ( 0 == strncmp( start, "RS1", stop - start ) ) { /* For now all these reserved entries seem to have the same value, which can be hardcoded to int(1699505740) for now */ entry->reserved = talloc_strdup(mem_ctx, "eLfL"); } else if ( 0 == strncmp( start, "RCN", stop - start ) ) { entry->record_number = atoi( stop + 1 ); } else if ( 0 == strncmp( start, "TMG", stop - start ) ) { entry->time_generated = atoi( stop + 1 ); } else if ( 0 == strncmp( start, "TMW", stop - start ) ) { entry->time_written = atoi( stop + 1 ); } else if ( 0 == strncmp( start, "EID", stop - start ) ) { entry->event_id = atoi( stop + 1 ); } else if ( 0 == strncmp( start, "ETP", stop - start ) ) { if ( strstr( start, "ERROR" ) ) { entry->event_type = EVENTLOG_ERROR_TYPE; } else if ( strstr( start, "WARNING" ) ) { entry->event_type = EVENTLOG_WARNING_TYPE; } else if ( strstr( start, "INFO" ) ) { entry->event_type = EVENTLOG_INFORMATION_TYPE; } else if ( strstr( start, "AUDIT_SUCCESS" ) ) { entry->event_type = EVENTLOG_AUDIT_SUCCESS; } else if ( strstr( start, "AUDIT_FAILURE" ) ) { entry->event_type = EVENTLOG_AUDIT_FAILURE; } else if ( strstr( start, "SUCCESS" ) ) { entry->event_type = EVENTLOG_SUCCESS; } else { /* some other eventlog type -- currently not defined in MSDN docs, so error out */ return False; } } /* else if(0 == strncmp(start, "NST", stop - start)) { entry->num_of_strings = atoi(stop + 1); } */ else if ( 0 == strncmp( start, "ECT", stop - start ) ) { entry->event_category = atoi( stop + 1 ); } else if ( 0 == strncmp( start, "RS2", stop - start ) ) { entry->reserved_flags = atoi( stop + 1 ); } else if ( 0 == strncmp( start, "CRN", stop - start ) ) { entry->closing_record_number = atoi( stop + 1 ); } else if ( 0 == strncmp( start, "USL", stop - start ) ) { entry->sid_length = atoi( stop + 1 ); } else if ( 0 == strncmp( start, "SRC", stop - start ) ) { stop++; while ( isspace( stop[0] ) ) { stop++; } entry->source_name_len = strlen_m_term(stop); entry->source_name = talloc_strdup(mem_ctx, stop); if (entry->source_name_len == (uint32_t)-1 || entry->source_name == NULL) { return false; } } else if ( 0 == strncmp( start, "SRN", stop - start ) ) { stop++; while ( isspace( stop[0] ) ) { stop++; } entry->computer_name_len = strlen_m_term(stop); entry->computer_name = talloc_strdup(mem_ctx, stop); if (entry->computer_name_len == (uint32_t)-1 || entry->computer_name == NULL) { return false; } } else if ( 0 == strncmp( start, "SID", stop - start ) ) { smb_ucs2_t *dummy = NULL; stop++; while ( isspace( stop[0] ) ) { stop++; } entry->sid_length = rpcstr_push_talloc(mem_ctx, &dummy, stop); if (entry->sid_length == (uint32_t)-1) { return false; } entry->sid = data_blob_talloc(mem_ctx, dummy, entry->sid_length); if (entry->sid.data == NULL) { return false; } } else if ( 0 == strncmp( start, "STR", stop - start ) ) { size_t tmp_len; int num_of_strings; /* skip past initial ":" */ stop++; /* now skip any other leading whitespace */ while ( isspace(stop[0])) { stop++; } tmp_len = strlen_m_term(stop); if (tmp_len == (size_t)-1) { return false; } num_of_strings = entry->num_of_strings; if (!add_string_to_array(mem_ctx, stop, &entry->strings, &num_of_strings)) { return false; } if (num_of_strings > 0xffff) { return false; } entry->num_of_strings = num_of_strings; entry->strings_len += tmp_len; } else if ( 0 == strncmp( start, "DAT", stop - start ) ) { /* skip past initial ":" */ stop++; /* now skip any other leading whitespace */ while ( isspace( stop[0] ) ) { stop++; } entry->data_length = strlen_m(stop); entry->data = data_blob_talloc(mem_ctx, stop, entry->data_length); if (!entry->data.data) { return false; } } else { /* some other eventlog entry -- not implemented, so dropping on the floor */ DEBUG( 10, ( "Unknown entry [%s]. Ignoring.\n", line ) ); /* For now return true so that we can keep on parsing this mess. Eventually we will return False here. */ return true; } return true; }