// mkdirWithACL creates a new directory. If there is an error, it will be of // type *PathError. . // // This is a modified and combined version of os.Mkdir and syscall.Mkdir // in golang to cater for creating a directory am ACL permitting full // access, with inheritance, to any subfolder/file for Built-in Administrators // and Local System. func mkdirWithACL(name string) error { sa := syscall.SecurityAttributes{Length: 0} sddl := "D:P(A;OICI;GA;;;BA)(A;OICI;GA;;;SY)" sd, err := winio.SddlToSecurityDescriptor(sddl) if err != nil { return &os.PathError{"mkdir", name, err} } sa.Length = uint32(unsafe.Sizeof(sa)) sa.InheritHandle = 1 sa.SecurityDescriptor = uintptr(unsafe.Pointer(&sd[0])) namep, err := syscall.UTF16PtrFromString(name) if err != nil { return &os.PathError{"mkdir", name, err} } e := syscall.CreateDirectory(namep, &sa) if e != nil { return &os.PathError{"mkdir", name, e} } return nil }
func (d *Driver) create(id, parent, mountLabel string, readOnly bool, storageOpt map[string]string) error { if len(storageOpt) != 0 { return fmt.Errorf("--storage-opt is not supported for windows") } rPId, err := d.resolveID(parent) if err != nil { return err } parentChain, err := d.getLayerChain(rPId) if err != nil { return err } var layerChain []string if rPId != "" { parentPath, err := hcsshim.GetLayerMountPath(d.info, rPId) if err != nil { return err } if _, err := os.Stat(filepath.Join(parentPath, "Files")); err == nil { // This is a legitimate parent layer (not the empty "-init" layer), // so include it in the layer chain. layerChain = []string{parentPath} } } layerChain = append(layerChain, parentChain...) if readOnly { if err := hcsshim.CreateLayer(d.info, id, rPId); err != nil { return err } } else { var parentPath string if len(layerChain) != 0 { parentPath = layerChain[0] } if isTP5OrOlder() { // Pre-create the layer directory, providing an ACL to give the Hyper-V Virtual Machines // group access. This is necessary to ensure that Hyper-V containers can access the // virtual machine data. This is not necessary post-TP5. path, err := syscall.UTF16FromString(filepath.Join(d.info.HomeDir, id)) if err != nil { return err } // Give system and administrators full control, and VMs read, write, and execute. // Mark these ACEs as inherited. sd, err := winio.SddlToSecurityDescriptor("D:(A;OICI;FA;;;SY)(A;OICI;FA;;;BA)(A;OICI;FRFWFX;;;S-1-5-83-0)") if err != nil { return err } err = syscall.CreateDirectory(&path[0], &syscall.SecurityAttributes{ Length: uint32(unsafe.Sizeof(syscall.SecurityAttributes{})), SecurityDescriptor: uintptr(unsafe.Pointer(&sd[0])), }) if err != nil { return err } } if err := hcsshim.CreateSandboxLayer(d.info, id, parentPath, layerChain); err != nil { return err } } if _, err := os.Lstat(d.dir(parent)); err != nil { if err2 := hcsshim.DestroyLayer(d.info, id); err2 != nil { logrus.Warnf("Failed to DestroyLayer %s: %s", id, err2) } return fmt.Errorf("Cannot create layer with missing parent %s: %s", parent, err) } if err := d.setLayerChain(id, layerChain); err != nil { if err2 := hcsshim.DestroyLayer(d.info, id); err2 != nil { logrus.Warnf("Failed to DestroyLayer %s: %s", id, err2) } return err } return nil }