/** * Store NT and LM hashes on an NTLMSSP context - ensures they are talloc()ed * */ NTSTATUS ntlmssp_set_hashes(NTLMSSP_STATE *ntlmssp_state, const unsigned char lm_hash[16], const unsigned char nt_hash[16]) { ntlmssp_state->lm_hash = (unsigned char *) TALLOC_MEMDUP(ntlmssp_state->mem_ctx, lm_hash, 16); ntlmssp_state->nt_hash = (unsigned char *) TALLOC_MEMDUP(ntlmssp_state->mem_ctx, nt_hash, 16); if (!ntlmssp_state->lm_hash || !ntlmssp_state->nt_hash) { TALLOC_FREE(ntlmssp_state->lm_hash); TALLOC_FREE(ntlmssp_state->nt_hash); return NT_STATUS_NO_MEMORY; } return NT_STATUS_OK; }
/** strdup_w with a talloc */ smb_ucs2_t *talloc_strdup_w(TALLOC_CTX *t, const smb_ucs2_t *p) { if (p) return TALLOC_MEMDUP(t, p, (strlen_w(p) + 1) * sizeof(smb_ucs2_t)); else return NULL; }
/** strdup with a talloc */ char *talloc_strdup(TALLOC_CTX *t, const char *p) { if (p) return TALLOC_MEMDUP(t, p, strlen(p) + 1); else return NULL; }
struct auth_serversupplied_info *copy_serverinfo(TALLOC_CTX *mem_ctx, const struct auth_serversupplied_info *src) { struct auth_serversupplied_info *dst; dst = make_server_info(mem_ctx); if (dst == NULL) { return NULL; } dst->guest = src->guest; dst->system = src->system; dst->utok.uid = src->utok.uid; dst->utok.gid = src->utok.gid; dst->utok.ngroups = src->utok.ngroups; if (src->utok.ngroups != 0) { dst->utok.groups = (gid_t *)TALLOC_MEMDUP( dst, src->utok.groups, sizeof(gid_t)*dst->utok.ngroups); } else { dst->utok.groups = NULL; } if (src->security_token) { dst->security_token = dup_nt_token(dst, src->security_token); if (!dst->security_token) { TALLOC_FREE(dst); return NULL; } } dst->user_session_key = data_blob_talloc( dst, src->user_session_key.data, src->user_session_key.length); dst->lm_session_key = data_blob_talloc(dst, src->lm_session_key.data, src->lm_session_key.length); dst->info3 = copy_netr_SamInfo3(dst, src->info3); if (!dst->info3) { TALLOC_FREE(dst); return NULL; } dst->extra = src->extra; dst->unix_name = talloc_strdup(dst, src->unix_name); if (!dst->unix_name) { TALLOC_FREE(dst); return NULL; } dst->sanitized_username = talloc_strdup(dst, src->sanitized_username); if (!dst->sanitized_username) { TALLOC_FREE(dst); return NULL; } return dst; }
DATA_BLOB data_blob_talloc(TALLOC_CTX *mem_ctx, const void *p, size_t length) { DATA_BLOB ret; if (!length) { ZERO_STRUCT(ret); return ret; } if (p) { ret.data = (uint8 *)TALLOC_MEMDUP(mem_ctx, p, length); if (ret.data == NULL) smb_panic("data_blob_talloc: TALLOC_MEMDUP failed.\n"); } else { ret.data = (uint8 *)TALLOC(mem_ctx, length); if (ret.data == NULL) smb_panic("data_blob_talloc: talloc failed.\n"); } ret.length = length; ret.free = NULL; return ret; }
BOOL smb_io_relarraystr(const char *desc, RPC_BUFFER *buffer, int depth, uint16 **string) { UNISTR chaine; prs_struct *ps=&buffer->prs; if (MARSHALLING(ps)) { uint32 struct_offset = prs_offset(ps); uint32 relative_offset; uint16 *p; uint16 *q; uint16 zero=0; p=*string; q=*string; /* first write the last 0 */ buffer->string_at_end -= 2; if(!prs_set_offset(ps, buffer->string_at_end)) return False; if(!prs_uint16("leading zero", ps, depth, &zero)) return False; while (p && (*p!=0)) { while (*q!=0) q++; /* Yes this should be malloc not talloc. Don't change. */ chaine.buffer = (uint16 *) SMB_MALLOC((q-p+1)*sizeof(uint16)); if (chaine.buffer == NULL) return False; memcpy(chaine.buffer, p, (q-p+1)*sizeof(uint16)); buffer->string_at_end -= (q-p+1)*sizeof(uint16); if(!prs_set_offset(ps, buffer->string_at_end)) { SAFE_FREE(chaine.buffer); return False; } /* write the string */ if (!smb_io_unistr(desc, &chaine, ps, depth)) { SAFE_FREE(chaine.buffer); return False; } q++; p=q; SAFE_FREE(chaine.buffer); } if(!prs_set_offset(ps, struct_offset)) return False; relative_offset=buffer->string_at_end - buffer->struct_start; /* write its offset */ if (!prs_uint32("offset", ps, depth, &relative_offset)) return False; } else { /* UNMARSHALLING */ uint32 old_offset; uint16 *chaine2=NULL; int l_chaine=0; int l_chaine2=0; size_t realloc_size = 0; *string=NULL; /* read the offset */ if (!prs_uint32("offset", ps, depth, &buffer->string_at_end)) return False; old_offset = prs_offset(ps); if(!prs_set_offset(ps, buffer->string_at_end + buffer->struct_start)) return False; do { if (!smb_io_unistr(desc, &chaine, ps, depth)) return False; l_chaine=str_len_uni(&chaine); /* we're going to add two more bytes here in case this is the last string in the array and we need to add an extra NULL for termination */ if (l_chaine > 0) { realloc_size = (l_chaine2+l_chaine+2)*sizeof(uint16); /* Yes this should be realloc - it's freed below. JRA */ if((chaine2=(uint16 *)SMB_REALLOC(chaine2, realloc_size)) == NULL) { return False; } memcpy(chaine2+l_chaine2, chaine.buffer, (l_chaine+1)*sizeof(uint16)); l_chaine2+=l_chaine+1; } } while(l_chaine!=0); /* the end should be bould NULL terminated so add the second one here */ if (chaine2) { chaine2[l_chaine2] = '\0'; *string=(uint16 *)TALLOC_MEMDUP(prs_get_mem_context(ps),chaine2,realloc_size); if (!*string) { return False; } SAFE_FREE(chaine2); } if(!prs_set_offset(ps, old_offset)) return False; } return True; }
REG_VALUE_DATA *cac_MakeRegValueData( TALLOC_CTX * mem_ctx, uint32 data_type, REGVAL_BUFFER buf ) { REG_VALUE_DATA *data; uint32 i; /*all of the following used for MULTI_SZ data */ uint32 size = 0; uint32 len = 0; uint32 multi_idx = 0; uint32 num_strings = 0; char **strings = NULL; data = talloc( mem_ctx, REG_VALUE_DATA ); if ( !data ) { errno = ENOMEM; return NULL; } switch ( data_type ) { case REG_SZ: data->reg_sz = cac_unistr_to_str( mem_ctx, buf.buffer, buf.buf_len ); if ( !data->reg_sz ) { TALLOC_FREE( data ); errno = ENOMEM; data = NULL; } break; case REG_EXPAND_SZ: data->reg_expand_sz = cac_unistr_to_str( mem_ctx, buf.buffer, buf.buf_len ); if ( !data->reg_expand_sz ) { TALLOC_FREE( data ); errno = ENOMEM; data = NULL; } break; case REG_BINARY: size = buf.buf_len; data->reg_binary.data_length = size; if (size) { data->reg_binary.data = ( uint8 * ) TALLOC_MEMDUP( mem_ctx, buf.buffer, size ); if ( !data->reg_binary.data ) { TALLOC_FREE( data ); errno = ENOMEM; data = NULL; } } else { data->reg_binary.data = NULL; } break; case REG_DWORD: data->reg_dword = *( ( uint32 * ) buf.buffer ); break; case REG_DWORD_BE: data->reg_dword_be = *( ( uint32 * ) buf.buffer ); break; case REG_MULTI_SZ: size = buf.buf_len; /*find out how many strings there are. size is # of bytes and we want to work uint16 */ for ( i = 0; i < ( size / 2 - 1 ); i++ ) { if ( buf.buffer[i] == 0x0000 ) num_strings++; /*buffer is suppsed to be terminated with \0\0, but it might not be */ if ( buf.buffer[i] == 0x0000 && buf.buffer[i + 1] == 0x0000 ) break; } if (num_strings) { strings = TALLOC_ARRAY( mem_ctx, char *, num_strings ); if ( !strings ) { errno = ENOMEM; TALLOC_FREE( data ); break; } } else { strings = NULL; } if ( num_strings == 0 ) /*then our work here is done */ break; for ( i = 0; i < num_strings; i++ ) { /*find out how many characters are in this string */ len = 0; /*make sure we don't go past the end of the buffer and keep looping until we have a uni \0 */ while ( multi_idx + len < size / 2 && buf.buffer[multi_idx + len] != 0x0000 ) len++; /*stay aware of the \0\0 */ len++; strings[i] = TALLOC_ZERO_ARRAY( mem_ctx, char, len ); /*pull out the unicode string */ rpcstr_pull( strings[i], ( buf.buffer + multi_idx ), len, -1, STR_TERMINATE ); /*keep track of where we are in the bigger array */ multi_idx += len; } data->reg_multi_sz.num_strings = num_strings; data->reg_multi_sz.strings = strings; break; default: TALLOC_FREE( data ); data = NULL; }
static BOOL parse_share_modes(TDB_DATA dbuf, struct share_mode_lock *lck) { struct locking_data *data; int i; if (dbuf.dsize < sizeof(struct locking_data)) { smb_panic("PANIC: parse_share_modes: buffer too short.\n"); } data = (struct locking_data *)dbuf.dptr; lck->delete_on_close = data->u.s.delete_on_close; lck->num_share_modes = data->u.s.num_share_mode_entries; DEBUG(10, ("parse_share_modes: delete_on_close: %d, " "num_share_modes: %d\n", lck->delete_on_close, lck->num_share_modes)); if ((lck->num_share_modes < 0) || (lck->num_share_modes > 1000000)) { DEBUG(0, ("invalid number of share modes: %d\n", lck->num_share_modes)); smb_panic("PANIC: invalid number of share modes"); } lck->share_modes = NULL; if (lck->num_share_modes != 0) { if (dbuf.dsize < (sizeof(struct locking_data) + (lck->num_share_modes * sizeof(struct share_mode_entry)))) { smb_panic("PANIC: parse_share_modes: buffer too short.\n"); } lck->share_modes = (struct share_mode_entry *) TALLOC_MEMDUP(lck, dbuf.dptr+sizeof(*data), lck->num_share_modes * sizeof(struct share_mode_entry)); if (lck->share_modes == NULL) { smb_panic("talloc failed\n"); } } /* Get any delete token. */ if (data->u.s.delete_token_size) { char *p = dbuf.dptr + sizeof(*data) + (lck->num_share_modes * sizeof(struct share_mode_entry)); if ((data->u.s.delete_token_size < sizeof(uid_t) + sizeof(gid_t)) || ((data->u.s.delete_token_size - sizeof(uid_t)) % sizeof(gid_t)) != 0) { DEBUG(0, ("parse_share_modes: invalid token size %d\n", data->u.s.delete_token_size)); smb_panic("parse_share_modes: invalid token size\n"); } lck->delete_token = TALLOC_P(lck, UNIX_USER_TOKEN); if (!lck->delete_token) { smb_panic("talloc failed\n"); } /* Copy out the uid and gid. */ memcpy(&lck->delete_token->uid, p, sizeof(uid_t)); p += sizeof(uid_t); memcpy(&lck->delete_token->gid, p, sizeof(gid_t)); p += sizeof(gid_t); /* Any supplementary groups ? */ lck->delete_token->ngroups = (data->u.s.delete_token_size > (sizeof(uid_t) + sizeof(gid_t))) ? ((data->u.s.delete_token_size - (sizeof(uid_t) + sizeof(gid_t)))/sizeof(gid_t)) : 0; if (lck->delete_token->ngroups) { /* Make this a talloc child of lck->delete_token. */ lck->delete_token->groups = TALLOC_ARRAY(lck->delete_token, gid_t, lck->delete_token->ngroups); if (!lck->delete_token) { smb_panic("talloc failed\n"); } for (i = 0; i < lck->delete_token->ngroups; i++) { memcpy(&lck->delete_token->groups[i], p, sizeof(gid_t)); p += sizeof(gid_t); } } } else { lck->delete_token = NULL; } /* Save off the associated service path and filename. */ lck->servicepath = talloc_strdup(lck, dbuf.dptr + sizeof(*data) + (lck->num_share_modes * sizeof(struct share_mode_entry)) + data->u.s.delete_token_size ); if (lck->servicepath == NULL) { smb_panic("talloc_strdup failed\n"); } lck->filename = talloc_strdup(lck, dbuf.dptr + sizeof(*data) + (lck->num_share_modes * sizeof(struct share_mode_entry)) + data->u.s.delete_token_size + strlen(lck->servicepath) + 1 ); if (lck->filename == NULL) { smb_panic("talloc_strdup failed\n"); } /* * Ensure that each entry has a real process attached. */ for (i = 0; i < lck->num_share_modes; i++) { struct share_mode_entry *entry_p = &lck->share_modes[i]; DEBUG(10,("parse_share_modes: %s\n", share_mode_str(i, entry_p) )); if (!process_exists(entry_p->pid)) { DEBUG(10,("parse_share_modes: deleted %s\n", share_mode_str(i, entry_p) )); entry_p->op_type = UNUSED_SHARE_MODE_ENTRY; lck->modified = True; } } return True; }