BUG: SeBackupPrivilege not honored by Vista when accessing SMB (version 1) shares
I’ve found a bug in how Vista treats SeBackupPrivilege when accessing network shares exported by SMB version 1 servers. Even after SeBackupPrivilege is enabled in a Vista session, the SMB packets created by calls to FindFirstFile()/FindNextFile() will result in Access Denied if the NTFS ACL’s on the server would block the caller’s request. The result is that backup applications running on Vista cannot backup shares hosted on Windows 2003.
I’ve captured a packet trace using Microsoft Network Monitor 3.2 and attached it to this message. I believe the error can be seen in Frame 19. If you examine the FindFirst2ParamaterBlock section, you will see that BackupIntent is set to find without backup intent. This is an error. The BackupIntent needs to be enabled.

Download full capture
Interesting Note: I examined a similar packet trace initiated from a W2k3 client accessing the W2k3 server and it shows that BackupIntent is enabled. The request therefore succeeded.What’s interesting is the problem does not manifest when accessing SMB2 exported shares. Vista clients have no difficulty accessing another Vista system acting as a server. The problem also does not manifest when W2k3 acts as a client accessing another W2k3 server (which is SMB version 1 to SMB version 1).
The problem only happens when accessing an SMB version 1 share exported from a W2k3 server, accessed from a Vista client.
The setup
On W2K3, create the folder C:\Temp\t\sub. Remove inheritance from the ACL of C:\Temp\t\sub. Set the owner to a non-administrator/”regular” user. Remove all other ACL’s. Share out C:\Temp
On Vista (32-bit Business Edition, SP1), open a command prompt as elevated Administrator. “NET USE” to the W2k3 share using the credentials of an account in the Backup Operator’s group of the W2k3 server.
Run the following program
#include "stdafx.h"
bool enablepriv(const TCHAR priv[]);
int recurse(TCHAR path[]);
int _tmain(int argc, _TCHAR* argv[]){
if (argc < 2) {
_tprintf(TEXT("usage: %s {path-name}\n"),argv[0]);
return -1;
}
if (enablepriv(SE_BACKUP_NAME) != TRUE)
return -1;
return recurse(argv[1]);
}
int recurse(TCHAR path[]) {
_tprintf(TEXT("DIR %s\\\n"),path);
TCHAR ppath[2048];
const size_t psz = 2048;
_tcscpy_s(ppath, psz, path);
_tcscat_s(ppath, psz, TEXT("\\*"));
WIN32_FIND_DATA fdata;
HANDLE hnd = FindFirstFile(ppath, &fdata);
if (hnd == INVALID_HANDLE_VALUE) {
_tprintf(TEXT("Can't access path %s, w32error %d\n"),path,GetLastError());
return -1;
}
do {
// skip '.' and '..'
if (_tcscmp(fdata.cFileName, TEXT(".")) == 0 || _tcscmp(fdata.cFileName,TEXT("..")) == 0)
continue;
if (fdata.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY) {
if (fdata.dwFileAttributes & FILE_ATTRIBUTE_REPARSE_POINT) {
// skip reparse points
}
else{
_tcscpy_s(ppath, psz, path);
_tcscat_s(ppath, psz, TEXT("\\"));
_tcscat_s(ppath, psz, fdata.cFileName);
if (recurse(ppath) != 0)
return -1;
}
}
else{
_tprintf(TEXT("FILE %s\\%s\n"),path, fdata.cFileName);
}
} while(FindNextFile(hnd, &fdata) != 0);
DWORD rc = GetLastError();
FindClose(hnd);
if (rc != ERROR_NO_MORE_FILES) {
_tprintf(TEXT("Error retrieving directory %s, w32error %d\n"),path,rc);
return -1;
}
return 0;
}
bool enablepriv(const TCHAR priv[]) {
HANDLE token;
if (!OpenThreadToken(GetCurrentThread(),TOKEN_QUERY | TOKEN_ADJUST_PRIVILEGES, TRUE, &token))
OpenProcessToken(GetCurrentProcess(), TOKEN_QUERY | TOKEN_ADJUST_PRIVILEGES, &token);
if (token == 0) {
_tprintf(TEXT("Unable to retrieve token. w32error %d\n"), GetLastError());
return FALSE;
}
LUID mluid;
if (0 == LookupPrivilegeValue(0, priv, &mluid)) {
_tprintf(TEXT("Can't lookup privilege %s, w32error %d\n"), priv, GetLastError());
return FALSE;
}
TOKEN_PRIVILEGES tp;
tp.PrivilegeCount = 1;
tp.Privileges[0].Attributes = SE_PRIVILEGE_ENABLED;
tp.Privileges[0].Luid = mluid;
if (0 == AdjustTokenPrivileges(token, FALSE, &tp, 0, 0, 0)) {
_tprintf(TEXT("Can't adjust privilege, w32error %d\n"), GetLastError());
return FALSE;
}
if (GetLastError() == ERROR_NOT_ALL_ASSIGNED) {
_tprintf(TEXT("You lack the necessary privileges to set %s\n"), priv);
return FALSE;
}
return TRUE;
}
Any insight offered would be greatly appreciated.
---
Jim C.
Jim C
Answers
Hi Jim:
As per our conversation over email, it appears that the solution delivered (hotfix) to you resolves the issue you are facing. This issue arises due to a Windows Vista bug . You documented the situation in which this bug manifests itself in excellent detail in your original posting. For the benefit of the community, I would like to clarify that the proper channel to get help on this problem is through Windows Support.
Thank you for bringing this issue to our attention.
Regards, Obaid Farooqi- Marked As Answer byJim1234 Friday, November 14, 2008 12:37 AM
All Replies
- Good morning Jim. I have alerted our Protocols Support team concerning your questions about [MS-SMB] and Vista SeBackupPrivilege. One of our team members will be in contact with you soon. Please note we may need to reroute your question to another internal team, as it might not be specific to the protocol documentation.
Thanks for your questions!
Escalation Engineer - Good Morning Jim C.
My name is Obaid Farooqi and I would be helping you with this case.
Regards, Obaid Farooqi - Sounds good Obaid. Let me know if I can provide further information.
Thanks
Jim C.
Jim C - Hi Obaid.
Sorry to be a pest, but we've been working on this for quite some time, and we're now roadblocked.
Is there an update?
Jim C - Good Afternoon Jim:
I am working on your problem. What exactly is the error you see on the Vista side when you run your program?
Regards, Obaid Farooqi - (note, first map W2k3 share as h: drive)
C:\> SMBTest h:\t
DIR h:\t\
DIR h:\t\sub\
Can't access path h:\t\sub, w32error 5
Obaid, any chance I can get your email address?
Jim C
Jim C - Good Afternoon Jim:
Looking at your code, I need info about a flag DF_NT_SMBS. Can you please send me the trace with negotiate command and response in it?
Regards, Obaid Farooqi - Obaid,
I'd be happy to do as you ask, but I'm not sure what flag you're referring to. I don't use DT_NT_SMB in the code. Can you clarify what you mean?
Jim
Jim C - Good Morning Jim:
I apologize for confusion. Please do not pay attention to the flag I mentioned. Please send me the trace with negotiate in it.
If you want to communicate through email there is a problem. Since this thread has public visibility, there may be people who are following this thread. Taking this thread private would be leaving other interested peoplebehind.
If you need to send me email (for something that you do not want to post or cannot post), you can send to dochelp@microsoft.com. Please mention the case number SRX081013600115 in the subject line.
Regards, Obaid Farooqi - No problem.
I wasn't able to figure out how to post a trace using the forum, so I linked to it in my original article. For quick reference, here's the URL to download the full trace
http://www.carroll.com/images/smbcapture.cap
Jim
Jim C - Good Morning Jim:
I looked at the trace but it does not have negotiate phase in it. Negotiate may happen earlier than running your program. It also may happen at the time you create the network drive. Here is how you can get a trace with negotiate in it.
1. Reboot your vista machine
2. start netmon.
3. create network drive
4. run your program.
Regards, Obaid Farooqi - Got it.
You can download the trace from
http://www.carroll.com/images/Negotiate-HsvistaLab.cap
The trace was made from the server side of the conversation (a machine called AS10) using Microsoft Network Monitor 3.2.
For completeness, I all took a snapshot of "whoami /all" of the account AS10\Backups which was used to negotiate the session.
C:\>whoami /all
USER INFORMATION
----------------
User Name SID
============ ==============================================
as10\backups S-1-5-21-1948780959-2201808987-1963200826-1029
GROUP INFORMATION
-----------------
Group Name Type SID Attributes
================================ ================ ============ ===============================================================
Everyone Well-known group S-1-1-0 Mandatory group, Enabled by default, Enabled group
BUILTIN\Users Alias S-1-5-32-545 Mandatory group, Enabled by default, Enabled group
BUILTIN\Backup Operators Alias S-1-5-32-551 Mandatory group, Enabled by default, Enabled group
BUILTIN\Remote Desktop Users Alias S-1-5-32-555 Mandatory group, Enabled by default, Enabled group
BUILTIN\Administrators Alias S-1-5-32-544 Mandatory group, Enabled by default, Enabled group, Group owner
NT AUTHORITY\INTERACTIVE Well-known group S-1-5-4 Mandatory group, Enabled by default, Enabled group
NT AUTHORITY\Authenticated Users Well-known group S-1-5-11 Mandatory group, Enabled by default, Enabled group
NT AUTHORITY\This Organization Well-known group S-1-5-15 Mandatory group, Enabled by default, Enabled group
LOCAL Well-known group S-1-2-0 Mandatory group, Enabled by default, Enabled group
NT AUTHORITY\NTLM Authentication Well-known group S-1-5-64-10 Mandatory group, Enabled by default, Enabled group
PRIVILEGES INFORMATION
----------------------
Privilege Name Description State
=============================== ========================================= ========
SeChangeNotifyPrivilege Bypass traverse checking Enabled
SeBackupPrivilege Back up files and directories Disabled
SeRestorePrivilege Restore files and directories Disabled
SeShutdownPrivilege Shut down the system Disabled
SeSecurityPrivilege Manage auditing and security log Disabled
SeSystemtimePrivilege Change the system time Disabled
SeRemoteShutdownPrivilege Force shutdown from a remote system Disabled
SeTakeOwnershipPrivilege Take ownership of files or other objects Disabled
SeDebugPrivilege Debug programs Disabled
SeSystemEnvironmentPrivilege Modify firmware environment values Disabled
SeSystemProfilePrivilege Profile system performance Disabled
SeProfileSingleProcessPrivilege Profile single process Disabled
SeIncreaseBasePriorityPrivilege Increase scheduling priority Disabled
SeLoadDriverPrivilege Load and unload device drivers Disabled
SeCreatePagefilePrivilege Create a pagefile Disabled
SeIncreaseQuotaPrivilege Adjust memory quotas for a process Disabled
SeUndockPrivilege Remove computer from docking station Disabled
SeManageVolumePrivilege Perform volume maintenance tasks Disabled
SeImpersonatePrivilege Impersonate a client after authentication Enabled
SeCreateGlobalPrivilege Create global objects Enabled
Jim C - Good Afternoon Jim C.:
The second trace has negotiate but it is missing the error part. Please send a trace from the very beginning (negotiate) all the way to the point where error happens.
If you have difficulty posting a big trace, you can email me at dochelp@microsoft.com. Please mention case number SRX081013600115 in the subject line.
Regards, Obaid Farooqi - Hi Obaid,
As requested, I performed the complete trace (from negotiate all the way through to the refused access), and sent it tou you via email.
Jim
Jim C Hi Jim:
As per our conversation over email, it appears that the solution delivered (hotfix) to you resolves the issue you are facing. This issue arises due to a Windows Vista bug . You documented the situation in which this bug manifests itself in excellent detail in your original posting. For the benefit of the community, I would like to clarify that the proper channel to get help on this problem is through Windows Support.
Thank you for bringing this issue to our attention.
Regards, Obaid Farooqi- Marked As Answer byJim1234 Friday, November 14, 2008 12:37 AM
Hi Obaid,
This bug in Vista is causing problems with our customers as well. Can you please post information or send me an email directly on how to access this hotfix?
Thanks,
Brian
For those who stumble across this thread in the future. The issue has been repaired by Microsoft. They've issued a HotFix which is discussed in Knowledge base article KB950790 (http://support.microsoft.com/kb/950790).
We've tested it successfully on ~1 billion files/folders in the lab and in the field. It has worked flawlessly for us.
Jim C


