#define AFSCALL_RXSTATS_DISABLE 0x2 /* Disable RX stats */
#define AFSCALL_RXSTATS_CLEAR 0x4 /* Clear RX stats */
+/* pioctl flags */
+
+#define AFSCALL_FLAG_LOCAL_SYSTEM 0x1
+
#ifndef __CM_IOCTL_INTERFACES_ONLY__
extern void cm_InitIoctl(void);
#pragma warning(disable: 4005)
#include <ntstatus.h>
#pragma warning(pop)
+#include <sddl.h>
#include <stddef.h>
#include <stdlib.h>
#include <malloc.h>
return uidp;
}
+afs_int32 smb_userIsLocalSystem(smb_user_t *uidp)
+{
+ SID *pSid = NULL;
+ DWORD dwSize1 = 0, dwSize2 = 0;
+ wchar_t *pszRefDomain = NULL;
+ SID_NAME_USE snu = SidTypeGroup;
+ clientchar_t * secSidString = NULL;
+ DWORD gle;
+ afs_int32 isSystem = 0;
+
+ /*
+ * The input name is probably not a SID for the user which is how
+ * the user is now being identified as a result of the SMB
+ * extended authentication. See if we can obtain the SID for the
+ * specified name. If we can, use that instead of the name
+ * provided.
+ */
+
+ LookupAccountNameW( NULL /* System Name to begin Search */,
+ uidp->unp->name,
+ NULL, &dwSize1,
+ NULL, &dwSize2,
+ &snu);
+ gle = GetLastError();
+ if (gle == ERROR_INSUFFICIENT_BUFFER) {
+ pSid = malloc(dwSize1);
+ /*
+ * Although dwSize2 is supposed to include the terminating
+ * NUL character, on Win7 it does not.
+ */
+ pszRefDomain = malloc((dwSize2 + 1) * sizeof(wchar_t));
+ }
+
+ if ( pSid && pszRefDomain ) {
+ memset(pSid, 0, dwSize1);
+
+ if (LookupAccountNameW( NULL /* System Name to begin Search */,
+ uidp->unp->name,
+ pSid, &dwSize1,
+ pszRefDomain, &dwSize2,
+ &snu))
+ ConvertSidToStringSidW(pSid, &secSidString);
+ }
+
+ if (secSidString) {
+ isSystem = !cm_ClientStrCmp(NTSID_LOCAL_SYSTEM, secSidString);
+ LocalFree(secSidString);
+ }
+
+ if (pSid)
+ free(pSid);
+ if (pszRefDomain)
+ free(pszRefDomain);
+
+ return isSystem;
+}
+
smb_username_t *smb_FindUserByName(clientchar_t *usern, clientchar_t *machine,
afs_uint32 flags)
{
#define NTNEGOTIATE_CAPABILITY_COMPRESSED 0x40000000L
#define NTNEGOTIATE_CAPABILITY_EXTENDED_SECURITY 0x80000000L
+#define NTSID_LOCAL_SYSTEM L"S-1-5-18"
+
/* a packet structure for receiving SMB messages; locked by smb_globalLock.
* Most of the work involved is in handling chained requests and responses.
*
extern smb_user_t *smb_FindUID(smb_vc_t *vcp, unsigned short uid, int flags);
+extern afs_int32 smb_userIsLocalSystem(smb_user_t *userp);
+
extern smb_username_t *smb_FindUserByName(clientchar_t *usern, clientchar_t *machine, afs_uint32 flags);
extern cm_user_t *smb_FindCMUserByName(clientchar_t *usern, clientchar_t *machine, afs_uint32 flags);
afs_int32 leftToCopy;
char *op;
afs_int32 code;
- cm_user_t *userp;
+ smb_user_t *uidp;
+ cm_user_t *userp = NULL;
+ smb_t *smbp;
+ int isSystem = 0;
iop = fidp->ioctlp;
count = smb_GetSMBParm(inp, 1);
- userp = smb_GetUserFromVCP(vcp, inp);
+
+ /* Get the user and determine if it is the local machine account */
+ smbp = (smb_t *) inp;
+ uidp = smb_FindUID(vcp, smbp->uid, 0);
+ if (uidp) {
+ isSystem = smb_userIsLocalSystem(uidp);
+ userp = smb_GetUserFromUID(uidp);
+ smb_ReleaseUID(uidp);
+ }
+
+ if (!userp) {
+ userp = cm_rootUserp;
+ cm_HoldUser(userp);
+ }
/* Identify tree */
code = smb_LookupTIDPath(vcp, ((smb_t *)inp)->tid, &iop->tidPathp);
- if(code) {
+ if (code) {
cm_ReleaseUser(userp);
return CM_ERROR_NOSUCHPATH;
}
/* turn the connection around, if required */
- code = smb_IoctlPrepareRead(fidp, iop, userp, 0);
+ code = smb_IoctlPrepareRead(fidp, iop, userp, isSystem ? AFSCALL_FLAG_LOCAL_SYSTEM : 0);
if (code) {
cm_ReleaseUser(userp);
uname = cm_ParseIoctlStringAlloc(&ioctlp->ioctl, tp);
tp += strlen(tp) + 1;
- if (flags & PIOCTL_LOGON) {
+ if ((pflags & AFSCALL_FLAG_LOCAL_SYSTEM) && (flags & PIOCTL_LOGON)) {
/* SMB user name with which to associate tokens */
smbname = cm_ParseIoctlStringAlloc(&ioctlp->ioctl, tp);
osi_Log2(smb_logp,"cm_IoctlSetToken for user [%S] smbname [%S]",
osi_Log0(smb_logp,"cm_IoctlSetToken - no name specified");
}
- if (flags & PIOCTL_LOGON) {
+ if ((pflags & AFSCALL_FLAG_LOCAL_SYSTEM) && (flags & PIOCTL_LOGON)) {
userp = smb_FindCMUserByName(smbname, ioctlp->fidp->vcp->rname,
SMB_FLAG_CREATE|SMB_FLAG_AFSLOGON);
release_userp = 1;
ucellp->flags |= CM_UCELLFLAG_RXKAD;
lock_ReleaseMutex(&userp->mx);
- if (flags & PIOCTL_LOGON) {
+ if ((pflags & AFSCALL_FLAG_LOCAL_SYSTEM) && (flags & PIOCTL_LOGON)) {
ioctlp->ioctl.flags |= CM_IOCTLFLAG_LOGON;
}