diff --git a/vendor/gopkg.in/jcmturner/rpc.v1/ndr/arrays.go b/vendor/gopkg.in/jcmturner/rpc.v1/ndr/arrays.go
new file mode 100644
index 0000000..5e2def2
--- /dev/null
+++ b/vendor/gopkg.in/jcmturner/rpc.v1/ndr/arrays.go
@@ -0,0 +1,413 @@
+package ndr
+
+import (
+	"errors"
+	"fmt"
+	"reflect"
+	"strconv"
+)
+
+// intFromTag returns an int that is a value in a struct tag key/value pair
+func intFromTag(tag reflect.StructTag, key string) (int, error) {
+	ndrTag := parseTags(tag)
+	d := 1
+	if n, ok := ndrTag.Map[key]; ok {
+		i, err := strconv.Atoi(n)
+		if err != nil {
+			return d, fmt.Errorf("invalid dimensions tag [%s]: %v", n, err)
+		}
+		d = i
+	}
+	return d, nil
+}
+
+// parseDimensions returns the a slice of the size of each dimension and type of the member at the deepest level.
+func parseDimensions(v reflect.Value) (l []int, tb reflect.Type) {
+	if v.Kind() == reflect.Ptr {
+		v = v.Elem()
+	}
+	t := v.Type()
+	if t.Kind() == reflect.Ptr {
+		t = t.Elem()
+	}
+	if t.Kind() != reflect.Array && t.Kind() != reflect.Slice {
+		return
+	}
+	l = append(l, v.Len())
+	if t.Elem().Kind() == reflect.Array || t.Elem().Kind() == reflect.Slice {
+		// contains array or slice
+		var m []int
+		m, tb = parseDimensions(v.Index(0))
+		l = append(l, m...)
+	} else {
+		tb = t.Elem()
+	}
+	return
+}
+
+// sliceDimensions returns the count of dimensions a slice has.
+func sliceDimensions(t reflect.Type) (d int, tb reflect.Type) {
+	if t.Kind() == reflect.Ptr {
+		t = t.Elem()
+	}
+	if t.Kind() == reflect.Slice {
+		d++
+		var n int
+		n, tb = sliceDimensions(t.Elem())
+		d += n
+	} else {
+		tb = t
+	}
+	return
+}
+
+// makeSubSlices is a deep recursive creation/initialisation of multi-dimensional slices.
+// Takes the reflect.Value of the 1st dimension and a slice of the lengths of the sub dimensions
+func makeSubSlices(v reflect.Value, l []int) {
+	ty := v.Type().Elem()
+	if ty.Kind() != reflect.Slice {
+		return
+	}
+	for i := 0; i < v.Len(); i++ {
+		s := reflect.MakeSlice(ty, l[0], l[0])
+		v.Index(i).Set(s)
+		// Are there more sub dimensions?
+		if len(l) > 1 {
+			makeSubSlices(v.Index(i), l[1:])
+		}
+	}
+	return
+}
+
+// multiDimensionalIndexPermutations returns all the permutations of the indexes of a multi-dimensional slice.
+// The input is a slice of integers that indicates the max size/length of each dimension
+func multiDimensionalIndexPermutations(l []int) (ps [][]int) {
+	z := make([]int, len(l), len(l)) // The zeros permutation
+	ps = append(ps, z)
+	// for each dimension, in reverse
+	for i := len(l) - 1; i >= 0; i-- {
+		ws := make([][]int, len(ps))
+		copy(ws, ps)
+		//create a permutation for each of the iterations of the current dimension
+		for j := 1; j <= l[i]-1; j++ {
+			// For each existing permutation
+			for _, p := range ws {
+				np := make([]int, len(p), len(p))
+				copy(np, p)
+				np[i] = j
+				ps = append(ps, np)
+			}
+		}
+	}
+	return
+}
+
+// precedingMax reads off the next conformant max value
+func (dec *Decoder) precedingMax() uint32 {
+	m := dec.conformantMax[0]
+	dec.conformantMax = dec.conformantMax[1:]
+	return m
+}
+
+// fillFixedArray establishes if the fixed array is uni or multi dimensional and then fills it.
+func (dec *Decoder) fillFixedArray(v reflect.Value, tag reflect.StructTag, def *[]deferedPtr) error {
+	l, t := parseDimensions(v)
+	if t.Kind() == reflect.String {
+		tag = reflect.StructTag(subStringArrayTag)
+	}
+	if len(l) < 1 {
+		return errors.New("could not establish dimensions of fixed array")
+	}
+	if len(l) == 1 {
+		err := dec.fillUniDimensionalFixedArray(v, tag, def)
+		if err != nil {
+			return fmt.Errorf("could not fill uni-dimensional fixed array: %v", err)
+		}
+		return nil
+	}
+	// Fixed array is multidimensional
+	ps := multiDimensionalIndexPermutations(l[:len(l)-1])
+	for _, p := range ps {
+		// Get current multi-dimensional index to fill
+		a := v
+		for _, i := range p {
+			a = a.Index(i)
+		}
+		// fill with the last dimension array
+		err := dec.fillUniDimensionalFixedArray(a, tag, def)
+		if err != nil {
+			return fmt.Errorf("could not fill dimension %v of multi-dimensional fixed array: %v", p, err)
+		}
+	}
+	return nil
+}
+
+// readUniDimensionalFixedArray reads an array (not slice) from the byte stream.
+func (dec *Decoder) fillUniDimensionalFixedArray(v reflect.Value, tag reflect.StructTag, def *[]deferedPtr) error {
+	for i := 0; i < v.Len(); i++ {
+		err := dec.fill(v.Index(i), tag, def)
+		if err != nil {
+			return fmt.Errorf("could not fill index %d of fixed array: %v", i, err)
+		}
+	}
+	return nil
+}
+
+// fillConformantArray establishes if the conformant array is uni or multi dimensional and then fills the slice.
+func (dec *Decoder) fillConformantArray(v reflect.Value, tag reflect.StructTag, def *[]deferedPtr) error {
+	d, _ := sliceDimensions(v.Type())
+	if d > 1 {
+		err := dec.fillMultiDimensionalConformantArray(v, d, tag, def)
+		if err != nil {
+			return err
+		}
+	} else {
+		err := dec.fillUniDimensionalConformantArray(v, tag, def)
+		if err != nil {
+			return err
+		}
+	}
+	return nil
+}
+
+// fillUniDimensionalConformantArray fills the uni-dimensional slice value.
+func (dec *Decoder) fillUniDimensionalConformantArray(v reflect.Value, tag reflect.StructTag, def *[]deferedPtr) error {
+	m := dec.precedingMax()
+	n := int(m)
+	a := reflect.MakeSlice(v.Type(), n, n)
+	for i := 0; i < n; i++ {
+		err := dec.fill(a.Index(i), tag, def)
+		if err != nil {
+			return fmt.Errorf("could not fill index %d of uni-dimensional conformant array: %v", i, err)
+		}
+	}
+	v.Set(a)
+	return nil
+}
+
+// fillMultiDimensionalConformantArray fills the multi-dimensional slice value provided from conformant array data.
+// The number of dimensions must be specified. This must be less than or equal to the dimensions in the slice for this
+// method not to panic.
+func (dec *Decoder) fillMultiDimensionalConformantArray(v reflect.Value, d int, tag reflect.StructTag, def *[]deferedPtr) error {
+	// Read the max size of each dimensions from the ndr stream
+	l := make([]int, d, d)
+	for i := range l {
+		l[i] = int(dec.precedingMax())
+	}
+	// Initialise size of slices
+	//   Initialise the size of the 1st dimension
+	ty := v.Type()
+	v.Set(reflect.MakeSlice(ty, l[0], l[0]))
+	// Initialise the size of the other dimensions recursively
+	makeSubSlices(v, l[1:])
+
+	// Get all permutations of the indexes and go through each and fill
+	ps := multiDimensionalIndexPermutations(l)
+	for _, p := range ps {
+		// Get current multi-dimensional index to fill
+		a := v
+		for _, i := range p {
+			a = a.Index(i)
+		}
+		err := dec.fill(a, tag, def)
+		if err != nil {
+			return fmt.Errorf("could not fill index %v of slice: %v", p, err)
+		}
+	}
+	return nil
+}
+
+// fillVaryingArray establishes if the varying array is uni or multi dimensional and then fills the slice.
+func (dec *Decoder) fillVaryingArray(v reflect.Value, tag reflect.StructTag, def *[]deferedPtr) error {
+	d, t := sliceDimensions(v.Type())
+	if d > 1 {
+		err := dec.fillMultiDimensionalVaryingArray(v, t, d, tag, def)
+		if err != nil {
+			return err
+		}
+	} else {
+		err := dec.fillUniDimensionalVaryingArray(v, tag, def)
+		if err != nil {
+			return err
+		}
+	}
+	return nil
+}
+
+// fillUniDimensionalVaryingArray fills the uni-dimensional slice value.
+func (dec *Decoder) fillUniDimensionalVaryingArray(v reflect.Value, tag reflect.StructTag, def *[]deferedPtr) error {
+	o, err := dec.readUint32()
+	if err != nil {
+		return fmt.Errorf("could not read offset of uni-dimensional varying array: %v", err)
+	}
+	s, err := dec.readUint32()
+	if err != nil {
+		return fmt.Errorf("could not establish actual count of uni-dimensional varying array: %v", err)
+	}
+	t := v.Type()
+	// Total size of the array is the offset in the index being passed plus the actual count of elements being passed.
+	n := int(s + o)
+	a := reflect.MakeSlice(t, n, n)
+	// Populate the array starting at the offset specified
+	for i := int(o); i < n; i++ {
+		err := dec.fill(a.Index(i), tag, def)
+		if err != nil {
+			return fmt.Errorf("could not fill index %d of uni-dimensional varying array: %v", i, err)
+		}
+	}
+	v.Set(a)
+	return nil
+}
+
+// fillMultiDimensionalVaryingArray fills the multi-dimensional slice value provided from varying array data.
+// The number of dimensions must be specified. This must be less than or equal to the dimensions in the slice for this
+// method not to panic.
+func (dec *Decoder) fillMultiDimensionalVaryingArray(v reflect.Value, t reflect.Type, d int, tag reflect.StructTag, def *[]deferedPtr) error {
+	// Read the offset and actual count of each dimensions from the ndr stream
+	o := make([]int, d, d)
+	l := make([]int, d, d)
+	for i := range l {
+		off, err := dec.readUint32()
+		if err != nil {
+			return fmt.Errorf("could not read offset of dimension %d: %v", i+1, err)
+		}
+		o[i] = int(off)
+		s, err := dec.readUint32()
+		if err != nil {
+			return fmt.Errorf("could not read size of dimension %d: %v", i+1, err)
+		}
+		l[i] = int(s) + int(off)
+	}
+	// Initialise size of slices
+	//   Initialise the size of the 1st dimension
+	ty := v.Type()
+	v.Set(reflect.MakeSlice(ty, l[0], l[0]))
+	// Initialise the size of the other dimensions recursively
+	makeSubSlices(v, l[1:])
+
+	// Get all permutations of the indexes and go through each and fill
+	ps := multiDimensionalIndexPermutations(l)
+	for _, p := range ps {
+		// Get current multi-dimensional index to fill
+		a := v
+		var os bool // should this permutation be skipped due to the offset of any of the dimensions?
+		for i, j := range p {
+			if j < o[i] {
+				os = true
+				break
+			}
+			a = a.Index(j)
+		}
+		if os {
+			// This permutation should be skipped as it is less than the offset for one of the dimensions.
+			continue
+		}
+		err := dec.fill(a, tag, def)
+		if err != nil {
+			return fmt.Errorf("could not fill index %v of slice: %v", p, err)
+		}
+	}
+	return nil
+}
+
+// fillConformantVaryingArray establishes if the varying array is uni or multi dimensional and then fills the slice.
+func (dec *Decoder) fillConformantVaryingArray(v reflect.Value, tag reflect.StructTag, def *[]deferedPtr) error {
+	d, t := sliceDimensions(v.Type())
+	if d > 1 {
+		err := dec.fillMultiDimensionalConformantVaryingArray(v, t, d, tag, def)
+		if err != nil {
+			return err
+		}
+	} else {
+		err := dec.fillUniDimensionalConformantVaryingArray(v, tag, def)
+		if err != nil {
+			return err
+		}
+	}
+	return nil
+}
+
+// fillUniDimensionalConformantVaryingArray fills the uni-dimensional slice value.
+func (dec *Decoder) fillUniDimensionalConformantVaryingArray(v reflect.Value, tag reflect.StructTag, def *[]deferedPtr) error {
+	m := dec.precedingMax()
+	o, err := dec.readUint32()
+	if err != nil {
+		return fmt.Errorf("could not read offset of uni-dimensional conformant varying array: %v", err)
+	}
+	s, err := dec.readUint32()
+	if err != nil {
+		return fmt.Errorf("could not establish actual count of uni-dimensional conformant varying array: %v", err)
+	}
+	if m < o+s {
+		return errors.New("max count is less than the offset plus actual count")
+	}
+	t := v.Type()
+	n := int(s)
+	a := reflect.MakeSlice(t, n, n)
+	for i := int(o); i < n; i++ {
+		err := dec.fill(a.Index(i), tag, def)
+		if err != nil {
+			return fmt.Errorf("could not fill index %d of uni-dimensional conformant varying array: %v", i, err)
+		}
+	}
+	v.Set(a)
+	return nil
+}
+
+// fillMultiDimensionalConformantVaryingArray fills the multi-dimensional slice value provided from conformant varying array data.
+// The number of dimensions must be specified. This must be less than or equal to the dimensions in the slice for this
+// method not to panic.
+func (dec *Decoder) fillMultiDimensionalConformantVaryingArray(v reflect.Value, t reflect.Type, d int, tag reflect.StructTag, def *[]deferedPtr) error {
+	// Read the offset and actual count of each dimensions from the ndr stream
+	m := make([]int, d, d)
+	for i := range m {
+		m[i] = int(dec.precedingMax())
+	}
+	o := make([]int, d, d)
+	l := make([]int, d, d)
+	for i := range l {
+		off, err := dec.readUint32()
+		if err != nil {
+			return fmt.Errorf("could not read offset of dimension %d: %v", i+1, err)
+		}
+		o[i] = int(off)
+		s, err := dec.readUint32()
+		if err != nil {
+			return fmt.Errorf("could not read actual count of dimension %d: %v", i+1, err)
+		}
+		if m[i] < int(s)+int(off) {
+			m[i] = int(s) + int(off)
+		}
+		l[i] = int(s)
+	}
+	// Initialise size of slices
+	//   Initialise the size of the 1st dimension
+	ty := v.Type()
+	v.Set(reflect.MakeSlice(ty, m[0], m[0]))
+	// Initialise the size of the other dimensions recursively
+	makeSubSlices(v, m[1:])
+
+	// Get all permutations of the indexes and go through each and fill
+	ps := multiDimensionalIndexPermutations(m)
+	for _, p := range ps {
+		// Get current multi-dimensional index to fill
+		a := v
+		var os bool // should this permutation be skipped due to the offset of any of the dimensions or max is higher than the actual count being passed
+		for i, j := range p {
+			if j < o[i] || j >= l[i] {
+				os = true
+				break
+			}
+			a = a.Index(j)
+		}
+		if os {
+			// This permutation should be skipped as it is less than the offset for one of the dimensions.
+			continue
+		}
+		err := dec.fill(a, tag, def)
+		if err != nil {
+			return fmt.Errorf("could not fill index %v of slice: %v", p, err)
+		}
+	}
+	return nil
+}
