static bool test_strlen_m(struct torture_context *tctx) { torture_assert_int_equal(tctx, strlen_m("foo"), 3, "simple len"); torture_assert_int_equal(tctx, strlen_m("foo\x83l"), 6, "extended len"); torture_assert_int_equal(tctx, strlen_m(""), 0, "empty"); torture_assert_int_equal(tctx, strlen_m(NULL), 0, "NULL"); return true; }
static enum ndr_err_code ndr_push_PAC_LOGON_NAME(struct ndr_push *ndr, int ndr_flags, const struct PAC_LOGON_NAME *r) { if (ndr_flags & NDR_SCALARS) { NDR_CHECK(ndr_push_align(ndr, 4)); NDR_CHECK(ndr_push_NTTIME(ndr, NDR_SCALARS, r->logon_time)); NDR_CHECK(ndr_push_uint16(ndr, NDR_SCALARS, 2 * strlen_m(r->account_name))); NDR_CHECK(ndr_push_charset(ndr, NDR_SCALARS, r->account_name, 2 * strlen_m(r->account_name), sizeof(uint8_t), CH_UTF16)); } if (ndr_flags & NDR_BUFFERS) { } return NDR_ERR_SUCCESS; }
/** Work out the number of multibyte chars in a string, including the NULL terminator. **/ _PUBLIC_ size_t strlen_m_term(const char *s) { if (!s) { return 0; } return strlen_m(s) + 1; }
_PUBLIC_ void ndr_print_PAC_LOGON_NAME(struct ndr_print *ndr, const char *name, const struct PAC_LOGON_NAME *r) { ndr_print_struct(ndr, name, "PAC_LOGON_NAME"); ndr->depth++; ndr_print_NTTIME(ndr, "logon_time", r->logon_time); ndr_print_uint16(ndr, "size", (ndr->flags & LIBNDR_PRINT_SET_VALUES)?2 * strlen_m(r->account_name):r->size); ndr_print_string(ndr, "account_name", r->account_name); ndr->depth--; }
/* Concatenates the src string to the end of the dest * string, returns the dest string * * You can assume that src/dest are '\0' terminated, * that dest hold enough space to store src+dest and * src/dest do not overlap in memory */ char* strcat_m(char* dest, char* src) { // first, find the end of the dest string. Then, // append src character by character; remember to add a '\0' // character at the end! int dest_len = strlen_m(dest); int src_len = strlen_m(src); // a very common mistake here is to include strlen_m(src) // as part of the loop condition. This is bad since // strlen_m(src) will be computed on every iteration of the loop, // resulting in a quadratic runtime for what is otherwise a linear // time operation for (int i = 0; i < src_len; i++) { dest[i + dest_len] = src[i]; } dest[src_len+dest_len] = '\0'; return dest; }
_PUBLIC_ size_t strlen_m_term_null(const char *s) { size_t len; if (!s) { return 0; } len = strlen_m(s); if (len == 0) { return 0; } return len+1; }
_PUBLIC_ enum ndr_err_code ndr_push_FILE_NOTIFY_INFORMATION(struct ndr_push *ndr, int ndr_flags, const struct FILE_NOTIFY_INFORMATION *r) { { uint32_t _flags_save_STRUCT = ndr->flags; ndr_set_flags(&ndr->flags, LIBNDR_FLAG_ALIGN4); if (ndr_flags & NDR_SCALARS) { NDR_CHECK(ndr_push_align(ndr, 4)); NDR_CHECK(ndr_push_uint32(ndr, NDR_SCALARS, r->NextEntryOffset)); NDR_CHECK(ndr_push_FILE_NOTIFY_ACTION(ndr, NDR_SCALARS, r->Action)); NDR_CHECK(ndr_push_uint32(ndr, NDR_SCALARS, strlen_m(r->FileName1) * 2)); { uint32_t _flags_save_uint16 = ndr->flags; ndr_set_flags(&ndr->flags, LIBNDR_FLAG_STR_NOTERM); NDR_CHECK(ndr_push_charset(ndr, NDR_SCALARS, r->FileName1, strlen_m(r->FileName1) * 2, sizeof(uint16_t), CH_UTF16)); ndr->flags = _flags_save_uint16; } NDR_CHECK(ndr_push_trailer_align(ndr, 4)); } if (ndr_flags & NDR_BUFFERS) { } ndr->flags = _flags_save_STRUCT; } return NDR_ERR_SUCCESS; }
/* Reverses a string and returns the a new string * containing the reversed string * * You can assume that str is '\0' terminated */ char* strrev(char *str) { // we allocate space for a new string (remember to leave space // for the '\0' character!) and then access // the characters in reverse. Don't forget the '\0' // character at the end! int str_len = strlen_m(str); char* rev_str = malloc(sizeof(char) * (str_len + 1)); for (int i = str_len-1; i >= 0; i--) { rev_str[str_len - i - 1] = str[i]; } rev_str[str_len] = '\0'; return rev_str; }
_PUBLIC_ void ndr_print_FILE_NOTIFY_INFORMATION(struct ndr_print *ndr, const char *name, const struct FILE_NOTIFY_INFORMATION *r) { ndr_print_struct(ndr, name, "FILE_NOTIFY_INFORMATION"); if (r == NULL) { ndr_print_null(ndr); return; } { uint32_t _flags_save_STRUCT = ndr->flags; ndr_set_flags(&ndr->flags, LIBNDR_FLAG_ALIGN4); ndr->depth++; ndr_print_uint32(ndr, "NextEntryOffset", r->NextEntryOffset); ndr_print_FILE_NOTIFY_ACTION(ndr, "Action", r->Action); ndr_print_uint32(ndr, "FileNameLength", (ndr->flags & LIBNDR_PRINT_SET_VALUES)?strlen_m(r->FileName1) * 2:r->FileNameLength); ndr_print_string(ndr, "FileName1", r->FileName1); ndr->depth--; ndr->flags = _flags_save_STRUCT; } }
/* append a string to the data section of a trans2 reply len_offset points to the place in the packet where the length field should go */ NTSTATUS smbsrv_blob_append_string(TALLOC_CTX *mem_ctx, DATA_BLOB *blob, const char *str, uint_t len_offset, int default_flags, int flags) { size_t ret; uint32_t offset; const int max_bytes_per_char = 3; offset = blob->length; BLOB_CHECK(smbsrv_blob_grow_data(mem_ctx, blob, offset + (2+strlen_m(str))*max_bytes_per_char)); ret = smbsrv_blob_push_string(mem_ctx, blob, len_offset, offset, str, -1, default_flags, flags); if (ret < 0) { return NT_STATUS_FOOBAR; } BLOB_CHECK(smbsrv_blob_grow_data(mem_ctx, blob, offset + ret)); return NT_STATUS_OK; }
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; }
/**************************************************************************** Create an auth_usersupplied_data structure after appropriate mapping. ****************************************************************************/ static NTSTATUS map_user_info_cracknames(struct ldb_context *sam_ctx, TALLOC_CTX *mem_ctx, const char *default_domain, const struct auth_usersupplied_info *user_info, struct auth_usersupplied_info **user_info_mapped) { char *domain; char *account_name; TALLOC_CTX *tmp_ctx = talloc_new(mem_ctx); WERROR werr; struct drsuapi_DsNameInfo1 info1; DEBUG(5,("map_user_info_cracknames: Mapping user [%s]\\[%s] from workstation [%s]\n", user_info->client.domain_name, user_info->client.account_name, user_info->workstation_name)); account_name = talloc_strdup(tmp_ctx, user_info->client.account_name); if (!account_name) { talloc_free(tmp_ctx); return NT_STATUS_NO_MEMORY; } /* use cracknames to work out what domain is being asked for */ if (strchr_m(user_info->client.account_name, '@') != NULL) { werr = DsCrackNameOneName(sam_ctx, tmp_ctx, 0, DRSUAPI_DS_NAME_FORMAT_USER_PRINCIPAL, DRSUAPI_DS_NAME_FORMAT_NT4_ACCOUNT, user_info->client.account_name, &info1); if (!W_ERROR_IS_OK(werr)) { DEBUG(2,("map_user_info: Failed cracknames of account '%s'\n", user_info->client.account_name)); talloc_free(tmp_ctx); return werror_to_ntstatus(werr); } switch (info1.status) { case DRSUAPI_DS_NAME_STATUS_OK: break; case DRSUAPI_DS_NAME_STATUS_NOT_FOUND: DEBUG(2,("map_user_info: Cracknames of account '%s' -> NOT_FOUND\n", user_info->client.account_name)); talloc_free(tmp_ctx); return NT_STATUS_NO_SUCH_USER; case DRSUAPI_DS_NAME_STATUS_DOMAIN_ONLY: DEBUG(2,("map_user_info: Cracknames of account '%s' -> DOMAIN_ONLY\n", user_info->client.account_name)); talloc_free(tmp_ctx); return NT_STATUS_NO_SUCH_USER; case DRSUAPI_DS_NAME_STATUS_NOT_UNIQUE: DEBUG(2,("map_user_info: Cracknames of account '%s' -> NOT_UNIQUE\n", user_info->client.account_name)); talloc_free(tmp_ctx); return NT_STATUS_NO_SUCH_USER; case DRSUAPI_DS_NAME_STATUS_RESOLVE_ERROR: DEBUG(2,("map_user_info: Cracknames of account '%s' -> RESOLVE_ERROR\n", user_info->client.account_name)); talloc_free(tmp_ctx); return NT_STATUS_NO_SUCH_USER; default: DEBUG(2,("map_user_info: Cracknames of account '%s' -> unknown error %u\n", user_info->client.account_name, info1.status)); talloc_free(tmp_ctx); return NT_STATUS_NO_SUCH_USER; } /* info1.result_name is in DOMAIN\username * form, which we need to split up into the * user_info_mapped structure */ domain = talloc_strdup(tmp_ctx, info1.result_name); if (domain == NULL) { talloc_free(tmp_ctx); return NT_STATUS_NO_MEMORY; } account_name = strchr_m(domain, '\\'); if (account_name == NULL) { DEBUG(2,("map_user_info: Cracknames of account '%s' gave invalid result '%s'\n", user_info->client.account_name, info1.result_name)); talloc_free(tmp_ctx); return NT_STATUS_NO_SUCH_USER; } *account_name = 0; account_name = talloc_strdup(tmp_ctx, account_name+1); if (account_name == NULL) { talloc_free(tmp_ctx); return NT_STATUS_NO_MEMORY; } } else { char *domain_name; if (user_info->client.domain_name && *user_info->client.domain_name) { domain_name = talloc_asprintf(tmp_ctx, "%s\\", user_info->client.domain_name); } else { domain_name = talloc_strdup(tmp_ctx, default_domain); } if (domain_name == NULL) { talloc_free(tmp_ctx); return NT_STATUS_NO_MEMORY; } werr = DsCrackNameOneName(sam_ctx, mem_ctx, 0, DRSUAPI_DS_NAME_FORMAT_NT4_ACCOUNT, DRSUAPI_DS_NAME_FORMAT_NT4_ACCOUNT, domain_name, &info1); if (!W_ERROR_IS_OK(werr)) { DEBUG(2,("map_user_info: Failed cracknames of domain '%s'\n", domain_name)); talloc_free(tmp_ctx); return werror_to_ntstatus(werr); } /* we use the account_name as-is, but get the * domain name from cracknames if possible */ account_name = talloc_strdup(mem_ctx, user_info->client.account_name); if (account_name == NULL) { talloc_free(tmp_ctx); return NT_STATUS_NO_MEMORY; } switch (info1.status) { case DRSUAPI_DS_NAME_STATUS_OK: case DRSUAPI_DS_NAME_STATUS_DOMAIN_ONLY: domain = talloc_strdup(tmp_ctx, info1.result_name); if (domain == NULL) { talloc_free(tmp_ctx); return NT_STATUS_NO_MEMORY; } if (domain[strlen_m(domain)-1] == '\\') { domain[strlen_m(domain)-1] = 0; } break; case DRSUAPI_DS_NAME_STATUS_NOT_FOUND: /* the domain is unknown - use the default domain */ domain = talloc_strdup(tmp_ctx, default_domain); break; case DRSUAPI_DS_NAME_STATUS_NOT_UNIQUE: DEBUG(2,("map_user_info: Cracknames of domain '%s' -> NOT_UNIQUE\n", domain_name)); talloc_free(tmp_ctx); return NT_STATUS_NO_SUCH_USER; case DRSUAPI_DS_NAME_STATUS_RESOLVE_ERROR: DEBUG(2,("map_user_info: Cracknames of domain '%s' -> RESOLVE_ERROR\n", domain_name)); talloc_free(tmp_ctx); return NT_STATUS_NO_SUCH_USER; default: DEBUG(2,("map_user_info: Cracknames of account '%s' -> unknown error %u\n", domain_name, info1.status)); talloc_free(tmp_ctx); return NT_STATUS_NO_SUCH_USER; } /* domain and account_name are filled in above */ } *user_info_mapped = talloc_zero(mem_ctx, struct auth_usersupplied_info); if (!*user_info_mapped) { talloc_free(tmp_ctx); return NT_STATUS_NO_MEMORY; } if (!talloc_reference(*user_info_mapped, user_info)) { talloc_free(tmp_ctx); return NT_STATUS_NO_MEMORY; } **user_info_mapped = *user_info; (*user_info_mapped)->mapped_state = true; (*user_info_mapped)->mapped.domain_name = talloc_strdup(*user_info_mapped, domain); (*user_info_mapped)->mapped.account_name = talloc_strdup(*user_info_mapped, account_name); talloc_free(tmp_ctx); if (!(*user_info_mapped)->mapped.domain_name || !(*user_info_mapped)->mapped.account_name) { return NT_STATUS_NO_MEMORY; } return NT_STATUS_OK; }
static void init_lsa_String(struct lsa_String *name, const char *s) { name->string = s; name->length = 2*strlen_m(s); name->size = name->length; }
void dump_reg_val(int lvl, const char *direction, const char *key, const char *subkey, struct registry_value *val) { int i = 0; const char *type_str = NULL; if (!val) { DEBUG(lvl,("no val!\n")); return; } type_str = str_regtype(val->type); DEBUG(lvl,("\tdump_reg_val:\t%s '%s'\n\t\t\t'%s' %s: ", direction, key, subkey, type_str)); switch (val->type) { case REG_DWORD: { uint32_t v; if (val->data.length < 4) { break; } v = IVAL(val->data.data, 0); DEBUG(lvl,("%d (0x%08x)\n", (int)v, v)); break; } case REG_QWORD: { uint64_t v; if (val->data.length < 8) { break; } v = BVAL(val->data.data, 0); DEBUG(lvl,("%d (0x%016llx)\n", (int)v, (unsigned long long)v)); break; } case REG_SZ: { const char *s; if (!pull_reg_sz(talloc_tos(), &val->data, &s)) { break; } DEBUG(lvl,("%s (length: %d)\n", s, (int)strlen_m(s))); break; } case REG_MULTI_SZ: { const char **a; if (!pull_reg_multi_sz(talloc_tos(), &val->data, &a)) { break; } for (i=0; a[i] != NULL; i++) { ;; } DEBUG(lvl,("(num_strings: %d)\n", i)); for (i=0; a[i] != NULL; i++) { DEBUGADD(lvl,("\t%s\n", a[i])); } break; } case REG_NONE: DEBUG(lvl,("\n")); break; case REG_BINARY: dump_data(lvl, val->data.data, val->data.length); break; default: DEBUG(lvl,("unsupported type: %d\n", val->type)); break; } }