2012-06-25

Another time related issue - leap seconds

It is NTP, again.
Besides the integer overflow issue, not VM oriented, there is also leap seconds issue.

2012-06-15

Command Parameters and special characters

An elaborated article: http://www.autohotkey.net/~deleyd/parameters/parameters.htm

Howto change file ownership in command line or by programming

Q: Changing file Ownership with PowerShell 2.0
A: Setting the owner on an ACL in Powershell

A tool is also provided by MS: takeown. But the latest comment is very interesting: he/she ended up with Cygwin's chown.
Next time, I would try both :)

And Copy&Pasted the blog from cosmoskey.blogspot.com for reference:

==================================================================================================================

I was trying to set the owner of an ACL in powershell using the following code:

PS C:\Users\Johan> $acl = get-acl c:\temp\acltest
PS C:\Users\Johan> $principal = New-Object Security.Principal.NTAccount "$env:computername\ownertestaccount"
PS C:\Users\Johan> $acl.psbase.SetOwner($principal)
PS C:\Users\Johan> set-acl -Path C:\Temp\acltest -AclObject $acl
Set-Acl : The security identifier is not allowed to be the owner of this object.
At line:1 char:8
+ set-acl <<<<  -Path C:\Temp\acltest -AclObject $acl
    + CategoryInfo          : InvalidOperation: (C:\Temp\acltest:String) [Set-Acl], InvalidOperationException
    + FullyQualifiedErrorId : System.InvalidOperationException,Microsoft.PowerShell.Commands.SetAclCommand


PS C:\Users\Johan>

So setting this ACL doesn't work. Why? I am an administrator! OK, what happens when I start the shell with Run As Administrator?... The same result.

So now we go to google and search a bit and I found the following KB article. What it says is that we need to have the rights to do the deed. Hey, not too surprising. By default Administrators and Backup Administrators have the Restore files and directories (SeRestorePrivilege) User Right. To set the owner we need to have this right, but in the scenario above I was executing the code with a account with all this privilege.

The problem here is that the privilege is not enabled in the access token, we need to call a function called AdjustTokenPrivileges() to adjust the current access token of our process. So we need to call this function, pass in a variable saying that we need to enable a privilege and pass in the privilege we want to enable. To call this function we need to do a little bit of PInvoke. I borrowed the base of my code from pinvoke.net.

So here is my little Set-Owner function.


function Set-Owner {
param(
[System.Security.Principal.IdentityReference]$Principal=$(throw "Mandatory parameter -Principal missing."),
$File=$(throw "Mandatory parameter -File missing.")
)
if(-not (Test-Path $file)){
throw "File $file is missing."
}
if($Principal -eq $null){
throw "Principal is NULL"
}


$code = @"
using System;
using System.Runtime.InteropServices;


namespace CosmosKey.Utils
{
public class TokenManipulator
{


[DllImport("advapi32.dll", ExactSpelling = true, SetLastError = true)]
internal static extern bool AdjustTokenPrivileges(IntPtr htok, bool disall,
ref TokPriv1Luid newst, int len, IntPtr prev, IntPtr relen);


[DllImport("kernel32.dll", ExactSpelling = true)]
internal static extern IntPtr GetCurrentProcess();


[DllImport("advapi32.dll", ExactSpelling = true, SetLastError = true)]
internal static extern bool OpenProcessToken(IntPtr h, int acc, ref IntPtr
phtok);


[DllImport("advapi32.dll", SetLastError = true)]
internal static extern bool LookupPrivilegeValue(string host, string name,
ref long pluid);


[StructLayout(LayoutKind.Sequential, Pack = 1)]
internal struct TokPriv1Luid
{
public int Count;
public long Luid;
public int Attr;
}


internal const int SE_PRIVILEGE_DISABLED = 0x00000000;
internal const int SE_PRIVILEGE_ENABLED = 0x00000002;
internal const int TOKEN_QUERY = 0x00000008;
internal const int TOKEN_ADJUST_PRIVILEGES = 0x00000020;


public const string SE_ASSIGNPRIMARYTOKEN_NAME = "SeAssignPrimaryTokenPrivilege";
public const string SE_AUDIT_NAME = "SeAuditPrivilege";
public const string SE_BACKUP_NAME = "SeBackupPrivilege";
public const string SE_CHANGE_NOTIFY_NAME = "SeChangeNotifyPrivilege";
public const string SE_CREATE_GLOBAL_NAME = "SeCreateGlobalPrivilege";
public const string SE_CREATE_PAGEFILE_NAME = "SeCreatePagefilePrivilege";
public const string SE_CREATE_PERMANENT_NAME = "SeCreatePermanentPrivilege";
public const string SE_CREATE_SYMBOLIC_LINK_NAME = "SeCreateSymbolicLinkPrivilege";
public const string SE_CREATE_TOKEN_NAME = "SeCreateTokenPrivilege";
public const string SE_DEBUG_NAME = "SeDebugPrivilege";
public const string SE_ENABLE_DELEGATION_NAME = "SeEnableDelegationPrivilege";
public const string SE_IMPERSONATE_NAME = "SeImpersonatePrivilege";
public const string SE_INC_BASE_PRIORITY_NAME = "SeIncreaseBasePriorityPrivilege";
public const string SE_INCREASE_QUOTA_NAME = "SeIncreaseQuotaPrivilege";
public const string SE_INC_WORKING_SET_NAME = "SeIncreaseWorkingSetPrivilege";
public const string SE_LOAD_DRIVER_NAME = "SeLoadDriverPrivilege";
public const string SE_LOCK_MEMORY_NAME = "SeLockMemoryPrivilege";
public const string SE_MACHINE_ACCOUNT_NAME = "SeMachineAccountPrivilege";
public const string SE_MANAGE_VOLUME_NAME = "SeManageVolumePrivilege";
public const string SE_PROF_SINGLE_PROCESS_NAME = "SeProfileSingleProcessPrivilege";
public const string SE_RELABEL_NAME = "SeRelabelPrivilege";
public const string SE_REMOTE_SHUTDOWN_NAME = "SeRemoteShutdownPrivilege";
public const string SE_RESTORE_NAME = "SeRestorePrivilege";
public const string SE_SECURITY_NAME = "SeSecurityPrivilege";
public const string SE_SHUTDOWN_NAME = "SeShutdownPrivilege";
public const string SE_SYNC_AGENT_NAME = "SeSyncAgentPrivilege";
public const string SE_SYSTEM_ENVIRONMENT_NAME = "SeSystemEnvironmentPrivilege";
public const string SE_SYSTEM_PROFILE_NAME = "SeSystemProfilePrivilege";
public const string SE_SYSTEMTIME_NAME = "SeSystemtimePrivilege";
public const string SE_TAKE_OWNERSHIP_NAME = "SeTakeOwnershipPrivilege";
public const string SE_TCB_NAME = "SeTcbPrivilege";
public const string SE_TIME_ZONE_NAME = "SeTimeZonePrivilege";
public const string SE_TRUSTED_CREDMAN_ACCESS_NAME = "SeTrustedCredManAccessPrivilege";
public const string SE_UNDOCK_NAME = "SeUndockPrivilege";
public const string SE_UNSOLICITED_INPUT_NAME = "SeUnsolicitedInputPrivilege";        


public static bool AddPrivilege(string privilege)
{
try
{
bool retVal;
TokPriv1Luid tp;
IntPtr hproc = GetCurrentProcess();
IntPtr htok = IntPtr.Zero;
retVal = OpenProcessToken(hproc, TOKEN_ADJUST_PRIVILEGES | TOKEN_QUERY, ref htok);
tp.Count = 1;
tp.Luid = 0;
tp.Attr = SE_PRIVILEGE_ENABLED;
retVal = LookupPrivilegeValue(null, privilege, ref tp.Luid);
retVal = AdjustTokenPrivileges(htok, false, ref tp, 0, IntPtr.Zero, IntPtr.Zero);
return retVal;
}
catch (Exception ex)
{
throw ex;
}


}
public static bool RemovePrivilege(string privilege)
{
try
{
bool retVal;
TokPriv1Luid tp;
IntPtr hproc = GetCurrentProcess();
IntPtr htok = IntPtr.Zero;
retVal = OpenProcessToken(hproc, TOKEN_ADJUST_PRIVILEGES | TOKEN_QUERY, ref htok);
tp.Count = 1;
tp.Luid = 0;
tp.Attr = SE_PRIVILEGE_DISABLED;
retVal = LookupPrivilegeValue(null, privilege, ref tp.Luid);
retVal = AdjustTokenPrivileges(htok, false, ref tp, 0, IntPtr.Zero, IntPtr.Zero);
return retVal;
}
catch (Exception ex)
{
throw ex;
}


}
}
}
"@


$errPref = $ErrorActionPreference
$ErrorActionPreference= "silentlycontinue"
$type = [CosmosKey.Utils.TokenManipulator]
$ErrorActionPreference = $errPref
if($type -eq $null){
add-type $code
}
$acl = Get-Acl $File
$acl.psbase.SetOwner($principal)
[void][CosmosKey.Utils.TokenManipulator]::AddPrivilege([CosmosKey.Utils.TokenManipulator]::SE_RESTORE_NAME)
set-acl -Path $File -AclObject $acl -passthru
[void][CosmosKey.Utils.TokenManipulator]::RemovePrivilege([CosmosKey.Utils.TokenManipulator]::SE_RESTORE_NAME)
}


If we run this function then we will see a very different result:

PS C:\Users\Johan> get-acl C:\Temp\acltest

    Directory: C:\Temp

Path               Owner                Access
----               -----                ------
acltest            MyLaptop\OldTest     BUILTIN\Administrators Allow  FullCo...


PS C:\Users\Johan> set-owner $(new-object security.principal.ntaccount "$env:computername\NewTest") C:\Temp\acltest

    Directory: C:\Temp

Path              Owner                Access
----              -----                ------
acltest           MyLaptop\NewTest     BUILTIN\Administrators Allow  FullCo...


PS C:\Users\Johan>

In the end we got there but it took me some time... :)

2012-06-06

琐事23

上周六,取草稿。

上周日,天色不好,窝家里。下午果然暴雨,持续时间倒是不长。
吃完晚饭,审美理发。
一则,一直没空去常去的理发店理发,头发太长了;二则,走到审美不过50m;三则,有一个优惠券,洗剪吹18.00。
指定理发店,自2007年就常去。算上这次,5年间,只有3次是在其他地方理发的。
一次是在育新花园路北的小理发店;剩下两次都是在这家审美,上次似乎花了38.00,只是稍稍剪短,所谓发型随便他折腾,没什么好,也没什么不好。
这次,很有吐槽点:据说是欧莱雅的师傅主刀,然后加上一个小姐,围着我疯狂推销欧莱雅的某款(滋养头皮、防治脱发、调理)产品(药品?)……
开始时,他们也没有直接推销,然后在附和他们的过程中,就被绕进去了。然后就一直不得安宁了:估计是暴雨的余威,加上时间比较晚了,再没有其他目标了。
不过理发倒是很给力:和平常一样,只要求耳朵上和脖颈处剪短一点,结果还真的往短了剪,理着理着,搞得我都有点恐慌了——不会搞成平头、板寸了吧……

周一,新sprint开始。
凌晨,老鼠在暖气片的复合板罩子里啃掉进去的报纸,把我吵醒了。轰不出来,只好在外面再用报纸粘的严严实实,把出路堵死。
晚上,看草稿。
老鼠继续在里面啃,还想钻出来,响动很大。半夜起来好几次……于是,亚马逊上定粘鼠板。

周二,one-one。
上午,收到粘鼠板。中午,饭后摆放粘鼠板,碗筷尚未收拾妥当,老鼠不知是被诱惑的,还是给吓到了,吱吱直叫,被轰到墙脚后,小命就玩完了。
晚上,探探网上别人的路线,骑了45km。天色暗下来才发现,尾灯拿去和老鼠斗阵后,忘了装回了。

2012-05-31

Hash algorithms

Either Murmur2 or FNV-1a would be a good fit, according to the answer on StackExchange.

2012-05-10

Syn Attack Protection

In a performance test, a bug was reported: a web application cannot handle clients' requests.

Server side:
  • more than 10k TIME_WAIT;
  • no error - no entry in Event Log or log files;
  • performance is OK (by measuring CPU, MEM, DISK, etc. using performance counter)
    • except the counts of received requests and processed requests are under expected
    • the count goes to 0 from certain time for certain clients in the order of test load (the most heavy working client gets blocked first)
  • the firewall is disabled
Client sides: all clients are running the same tests using the same test tool, except for the test data and test load
  • for certain client, if it fails, it fails forever
  • generates the following exception: System.Net.WebException: The request was aborted: Could not create SSL/TLS secure channel.
There seems no obvious errors in source code, both server side and client side.

Finally, I figure out it could possibly be the Syn Attack Protection problem, which is enabled by default and cannot be changed since Windows Vista.
In our case it's not like a typical syn flood attack, but based on the Cause analysis of the "General Network Error" of BizTalk, it could possibly be a Syn Attack, and protected by Windows 2008 SP1.

Other resources:
Next Generation TCP/IP Stack (and especially the changes to registry)
WinNT TCP/IP May Reuse TIME-WAIT Connections Prior to 2MSL

Too many TIME_WAIT:
System.Diagnostics.Stopwatch/QueryPerformanceCounter not working on Amazon AWS, other symptoms, and the solution
The cost on server side
The socket also ties up that particular src/dst IP address and port so it cannot be reused for the duration of the TIME_WAIT interval. (This is the intended purpose of the TIME_WAIT state.) Tying up the port is not usually an issue unless you need to reconnect a with the same port pair. Most often one side will use an ephemeral port, with only one side anchored to a well known port. However, a very large number of TIME_WAIT sockets can exhaust the ephemeral port space if you are repeatedly and frequently connecting between the same two IP addresses. Note this only affects this particular IP address pair, and will not affect establishment of connections with other hosts.

HttpWebRequest related
Howto keep connection live
Timing out after awhile;

Worth a read
Avoiding TCP/IP Port Exhaustion: only the Cause section
A short explanation on TIME_WAIT
TIME_WAIT Effects on Busy Servers: maybe outdated, and tested on SunOS
64k ephemeral port limit is per IP address, not per machine

Outdated
Configure the max limit for concurrent TCP connections
How to harden the TCP/IP stack against denial of service attacks in Windows Server 2003
Registry Settings that can be Modified to Improve Network Performance
Exhaustion of the ephemeral ports
Problems when you make Web service requests from ASP.NET applications
TCP settings that can impact BizTalk Server
MaxUserPort and TcpTimedWaitDelay