Wednesday 25 February 2015

Linux: Creating undeletable file that users can read/write to

Hey all,

Came across an interesting question today. Basically they wanted to create a file that a user could read/write to but not delete the file. I have a simple solution to this!! Using the "Restricted Delete Flag" of chmod when applied to a folder. Basically by creating a folder and enabling the "Restricted Delete Flag" on the folder allows users the permissions within the folder assigned to the specific files, however users with write access to a file cannot delete it. (Only the original user can delete it)
Any way here was/is my solution that will allow a user rw access to a file but be unable to delete it.

First create a folder: mkdir newfolder
Then set the restricted deletion flag on the folder: chmod 1705 newfolder/
Then in the folder create your new file
touch file
Set permissions: chmod 600 file
Then grant the user access: setfacl -m u:theuser:rw file

When you check the permissions using getfacl it should look something like this:
[root@ripper folder]# getfacl file
# file: file
# owner: root
# group: root
user::rw-
user:theuser:rw-
group::r--
mask::rw-
other::---

[root@ripper theuser]# getfacl folder
# file: folder
# owner: root
# group: root
# flags: --t
user::rwx
group::---
other::r-x


Now if you test your user can write to the file but will be unable to delete the file..
[theuser@ripper folder]$ cat file
[
theuser@ripper folder]$ echo testing | tee -a file
testing
[
theuser@ripper folder]$ cat file
testing
[
theuser@ripper folder]$ rm file
rm: cannot remove ‘file’: Permission denied
[
theuser@ripper folder]$ ls -alh file
-rw-rw----+ 1 root root 8 Feb 25 21:39 file
 

Much yays. Comments below if you have any other interesting ways of doing this.. Or if you get stuck doing this :)

Tuesday 24 February 2015

USMT Between Windows XP and Windows 8.1

Hey!

Becuase things always like to run smoothly and as painless as possible for us people in IT.... If you happen to be lucky enough to try get USMT working between XP and Win8.1 you will find that "shit just don't work". USMT 5 which works on XP does not work on Win 8.1, likewise USMT 6.3 does not work on XP.. ffs you say. Well don't worry I hacked up some hard work for you.

Just chuck USMT src in some location and this script will run the correct version for you.. YAY! (YOU NEED TO FIX THE SCRIPT TO YOUR ENVIRONMENT FIRST!!!!!!!)

FYI if you have no idea what the script is doing then just ask, if you know what it is doing then I hope you know how to fix it for your own environment.. If not just ask. I am feeling lazy and don't feel like explaining this at the moment(eg time of writing) :)

Either way I hope it gives people an idea to make things slightly easier

Option Explicit
Public Const WindowHidden = 0
Public Const ForReading = 1
Public Const ForWriting = 2
Public Const ForAppending = 8
Dim objShell: Set objShell = CreateObject("WScript.Shell")
Dim objFSO: Set objFSO = CreateObject("Scripting.FilesystemObject")
Dim strThisComputer: strThisComputer = objShell.ExpandEnvironmentStrings("%ComputerName%")
Dim strMigBasePath: strMigBasePath = "c:\MIG"
Dim cMD, iRes
Dim intBit
Dim strDestComputer
Dim strComputer: strComputer = "."
Dim objWMI, colOperatingSystems
Dim i, strOSVer, f, bHLink
Dim strUSMTSrc: strUSMTSrc = "c:\USMTSTUFF"
Dim strStorePath: strStorePath = "\USMT"
Dim strDestFile: strDestFile = "c:\dest.txt"
Dim strDExist: strDExist = False
Dim strMode
bHLink = False 'default to no hardlink
GetArgs()
If strMode = "SCAN" Then
'run scanstate tasks
wscript.echo "Running ScanState tasks"
ChkPath(strMigBasePath)
ChkOSVer()
GetUSMTSrc()
ChkDestAlive()
RunScanState()
Else
'run loadstate tasks
wscript.echo "Running LoadState tasks"
ChkPath(strMigBasePath)
ChkPath("c:"&strStorePath)
SharePath()
ChkOSVer()
GetUSMTSrc()
ChkDrive()
RunLoadState()
End If
'will only get this far if successful
wscript.echo "SUCCESSFULLY COMPLETED"
Wscript.quit(0)
Sub GetArgs()
Dim colNamedArgs
strMode = "NA"
Set colNamedArgs = WScript.Arguments.Named
If colNamedArgs.Exists(UCase("MODE")) Then
Select Case UCase(colNamedArgs.Item(UCase("MODE")))
Case "SCAN"
strMode = "SCAN"
Case "LOAD"
strMode = "LOAD"
Case Else
strMode = "NA"
End Select
End If
If strMode = "NA" Then
WScript.Echo "/Mode not defined"
WScript.Quit(-99)
End If
End Sub
Sub SharePath()
cMD = "net share usmt=c:\usmt /GRANT:Everyone,FULL"
iRes = objShell.Run(cMD, WindowHidden, True)
If iRes <> 0 Then
wscript.echo "Error creating share: " & iRes
wscript.quit(-1)
Else
wscript.echo "SUCCESS creating USMT share!"
End If
cMD = "Icacls c:\usmt /grant Everyone:F /inheritance:e /T"
iRes = objShell.Run(cMD, WindowHidden, True)
If iRes <> 0 Then
wscript.echo "Error fixing share permissions: " & iRes
wscript.quit(-1)
Else
wscript.echo "SUCCESS fixing share permissions!"
End If
End Sub
Sub ChkOSVer()
'get OS version
Set objWMI = GetObject("winmgmts:{impersonationLevel=impersonate}!\\" & strComputer & "\root\cimv2")
Set colOperatingSystems = objWMI.ExecQuery("Select * from Win32_OperatingSystem")
For Each i in colOperatingSystems
strOSVer = i.Version
Next
Select Case Mid(strOSVer,1,3)
Case "5.1"
strOSVer = "XP"
strUSMTSrc = strUSMTSrc & "\USMT5"
Case "6.1"
strOSVer = "7"
strUSMTSrc = strUSMTSrc & "\USMT6.3"
Case "6.2"
strOSVer = "8"
strUSMTSrc = strUSMTSrc & "\USMT6.3"
Case "6.3"
strOSVer = "8.1"
strUSMTSrc = strUSMTSrc & "\USMT6.3"
Case Else
'dont know about you
wscript.echo "ERROR UNKNOWN OS"
Wscript.Quit(-1)
End Select
'What Arch are we running 32 or 64bit?
intBit = GetObject("winmgmts:root\cimv2:Win32_Processor='cpu0'").AddressWidth
If intBit = 32 Then
'build 32bit path to USMT
strUSMTSrc = strUSMTSrc & "\x86\"
Else
'build 64bit path to USMT
strUSMTSrc = strUSMTSrc & "\amd64\"
End If
End Sub
Sub GetUSMTSrc()
'Get the files
cMD = "xcopy.exe """ & strUSMTSrc & "*.*"" " & strMigBasePath & "\ /s /y"
iRes = objShell.Run (cMD, WindowHidden, True)
If iRes <> 0 Then
Wscript.Echo "Error moving USMT files"
WScript.Quit(-1)
End If
'move the xml templates that drive scanstate
cMD = "xcopy.exe """ & strUSMTSrc & "\..\..\conf\*.*"" " & strMigBasePath & "\ /s /y"
iRes = objShell.Run (cMD, WindowHidden, True)
If iRes <> 0 Then
Wscript.Echo "Error moving USMT xml"
WScript.Quit(-1)
End If
End Sub
Sub ChkDestAlive()
'find the dest computer
If Not objFSO.FileExists(strDestFile) Then
strDestComputer = Inputbox("Please enter the destination computername","Input Required")
If strDestComputer = "" Then
'no input detected
wscript.echo "No destination computer defined. Quiting"
WScript.Quit(-1)
End If
Else
Set f = objFSO.OpenTextFile(strDestFile, FORREADING)
strDestComputer = f.ReadLine
f.Close
End If
strStorePath = "\\" & strDestComputer & strStorePath
If UCase(strDestComputer) = "LOCALHOST" Or UCase(strDestComputer) = UCase(strThisComputer) Then
'assume we want a hardlink
bHLink = True
Else
'make sure we can connect to the dest
Set f = objFSO.CreateTextFile("c:\chkdest.txt",True)
f.Write "check" & vbCrLf
f.Close
cMD = "xcopy.exe c:\chkdest.txt " & strStorePath & "\ /y"
iRes = objShell.Run(cMD, WindowHidden, True)
If iRes <> 0 Then
wscript.echo "Error connecting to destination computer"
Wscript.Quit(-1)
End If
End If
End Sub
Sub RunScanState()
'Build USMT scanstate
cMD = strMigBasePath & "\scanstate.exe" & " " & strStorePath &_
" /o" &_
" /ue:" & strThisComputer & "\Administrator" &_
" /ue:" & strThisComputer & "\Admin" &_
" /UEL:365" &_
" /Config:c:\mig\config.xml" &_
" /i:c:\mig\Mig.xml" &_
" /i:c:\mig\MigApp.xml" &_
" /i:c:\mig\MigDocs.xml" &_
" /i:c:\mig\MigUser.xml" &_
" /v:13 /l:c:\scanstate.log"
If bHLink Then cMD = cMD & " /hardlink /nocompress"
iRes = objShell.Run(cMD, WindowHidden, True)
If iRes <> 0 Then
wscript.echo "Error Received running scanstate: " & iRes
wscript.quit(-1)
Else
wscript.echo "SUCCESS!"
End If
'copy the scanstate log so the dest knows it can restore
cMD = "xcopy.exe c:\scanstate.log " & strStorePath & "\ /y"
iRes = objShell.Run(cMD, WindowHidden, True)
If iRes <> 0 Then
wscript.echo "Error connecting to destination computer"
Wscript.Quit(-1)
End If
If bHLink Then
'put a file so loadstate knows it is a hardlink
Set f = objFSO.CreateTextFile("c:\usmt\HARDLINK.txt",True)
f.Write "HARDLINK" & vbCrLf
f.Close
End If
End Sub
Sub RunLoadState()
'Build USMT loadstate
Dim intSleep: intSleep = 120 * 1000 '120 seconds.. * 1000 is because it is in ms..
Dim strScanStateLoc: strScanStateLoc = "c:\usmt\scanstate.log"
Dim strMigXML: strMigXML = "c:\mig\Mig.xml"
'pre check to see if this is a hardlink store
If objFSO.FileExists("c:\usmt\HARDLINK.txt") Then
'we are restoring from a hardlink
bHLink = True
End If
cMD = strMigBasePath & "\loadstate.exe C:\usmt" &_
" /ue:" & strThisComputer & "\Administrator" &_
" /ue:" & strThisComputer & "\Admin" &_
" /i:" & strMigXML &_
" /i:c:\mig\MigApp.xml" &_
" /i:c:\mig\MigDocs.xml" &_
" /i:c:\mig\MigUser.xml" &_
" /v:13 /l:c:\loadstate.log"
If bHLink Then cMD = cMD & " /hardlink /nocompress"
wscript.echo cMD
'make sure the scanstate.log exists
Do While Not objFSO.FileExists(strScanStateLoc)
wscript.echo "Waiting for scanstate...."
wscript.sleep intSleep
Loop
iRes = objShell.Run(cMD, WindowHidden, True)
If iRes <> 0 Then
wscript.echo "Error Received running loadstate: " & iRes
wscript.quit(-1)
Else
wscript.echo "SUCCESS!"
End If
End Sub
Sub ChkDrive()
If objFSO.DriveExists("D:") Then
strDExist = True
End If
End Sub
Function ChkPath(thePath)
'does path exist
If Not objFSO.FolderExists(thePath) Then
Dim aTemp, d, p
'build path
aTemp = split(thePath,InStrRev(thePath,"\"))
p = ""
For Each d in aTemp
If p <> "" Then p = p & "\"
p = p&d
If Not objFSO.FolderExists(p) Then objFSO.CreateFolder(p)
Next
End If