2012-09-13

退税,以及欧盟、欧元区、申根国的区别

主要参考:[實用資訊] 歐盟.歐元區.申根國傻傻分不清楚 暨 各種退稅方式

退税(有多种渠道和方式,我估计也就只会涉及下面两种):
* Global Blue 机场退税
* Amazon.de 网购退税
送货地址和账单(RECHNUNG)地址可以分开,账单地址需要为欧盟外国家或地区,邮寄地址可以为欧盟境内(免费送货)的地址。
拿着RECHNUNG在机场海关盖章。(机场海关还会再夹一张表格?)
将以下东西寄给Amazon.de:
原件:海关盖章的RECHNUNG
复印件:护照的首页、签证页、出入境页
地址如下:
Amazon.de
Umsatzsteuererstattung
Im Gewerbepark D 55
93059 Regensburg
Deutschland

申根(签证)主要是和出入境相关的。
欧盟主要和退税相关。
欧元区是指当地主要流通货币是欧元。

我在amazon.de(据说和.uk, .us是一个账户;但和.cn的账户是用不了的)上注册了个账号,然后就退税提问,下面是回答的主体——应该是同一模版,没有细节,也没有回答我的具体问题。结合网上的一些中文信息,可以有个大体了解,可能实际操作也很简单、没有各种坑,就没有人有动力提供详细攻略了。

From: cs-reply@amazon.de
To qualify for the refund, the following legal deadline must be met: the item must be exported before the third calendar month following the month in which the goods were received has expired.

For legal reason, we require proof that:

*your residence is abroad (*non*EU) as far as this is not evident from the export certificate, and
*that the items you purchased from Amazon.de have been declared at the customs

Please send both documents as well as the original invoice (essential!) to the following address:

Amazon.de
Umsatzsteuererstattung
Im Gewerbepark D 55
93059 Regensburg
Deutschland

We will keep the original invoice and the confirmation for our records. If you need a copy of your invoices, please tell us the respective order numbers and we will send you the copies.

2012-07-17

Time sync issues - SQL Server login

There is weird problem occurred just yesterday: in the same domain, using the same domain account (Windows Authentication), but on two different computers, everything is fine on the first computer (which is the domain controller); but, one the other computer it is impossible to connect to SQL Server DB (which is also in the same domain).

We doubted our own program first, so we tried SQL Server Management Studio, and it also failed, mentioning "Failed to generate SSPI context".
Then, we switched from FQDN to IP address, succeeded but seems a little bit slower than normal.
So, we doubted the DNS server - running nslookup - but it's fine.

We compared every possible differences might exist between the two, finally there is the one: the second computer has the year as 2010 instead of 2012!
As it is a shared testing environment, it is hard to know and remember who did the change and why.

The reason is that for security the time is critical and a much longer one which is knowledge oriented not problem concentrated.
And this could be in a more subtle: different time zone showing the same time.

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。天色暗下来才发现,尾灯拿去和老鼠斗阵后,忘了装回了。