cm_user_t *up = NULL;
uidp = smb_FindUID(vcp, inp->uid, 0);
- if (!uidp) return NULL;
+ if (!uidp)
+ return NULL;
lock_ObtainMutex(&uidp->mx);
if (uidp->unp) {
return inp;
}
-/*DEBUG do not checkin*/
void OutputDebugF(char * format, ...) {
va_list args;
int len;
OutputDebugString(buf);
}
}
-/**/
#define SMB_EXT_SEC_PACKAGE_NAME "Negotiate"
+
void smb_NegotiateExtendedSecurity(void ** secBlob, int * secBlobLength) {
SECURITY_STATUS status, istatus;
CredHandle creds = {0,0};
&creds,
&expiry);
- if (status != SEC_E_OK) {
+ if (status != SEC_E_OK) {
/* Really bad. We return an empty security blob */
OutputDebugF("AcquireCredentialsHandle failed with %lX", status);
goto nes_0;
lmAuth.lmlogon.LogonDomainName.Buffer = lmAuth.primaryDomainW;
mbstowcs(lmAuth.primaryDomainW, primaryDomain, P_LEN);
- lmAuth.lmlogon.LogonDomainName.Length = wcslen(lmAuth.primaryDomainW) * sizeof(WCHAR);
+ lmAuth.lmlogon.LogonDomainName.Length = (USHORT)(wcslen(lmAuth.primaryDomainW) * sizeof(WCHAR));
lmAuth.lmlogon.LogonDomainName.MaximumLength = P_LEN * sizeof(WCHAR);
lmAuth.lmlogon.UserName.Buffer = lmAuth.accountNameW;
mbstowcs(lmAuth.accountNameW, accountName, P_LEN);
- lmAuth.lmlogon.UserName.Length = wcslen(lmAuth.accountNameW) * sizeof(WCHAR);
+ lmAuth.lmlogon.UserName.Length = (USHORT)(wcslen(lmAuth.accountNameW) * sizeof(WCHAR));
lmAuth.lmlogon.UserName.MaximumLength = P_LEN * sizeof(WCHAR);
lmAuth.lmlogon.Workstation.Buffer = lmAuth.workstationW;
lmAuth.lmlogon.Workstation.MaximumLength = (MAX_COMPUTERNAME_LENGTH + 1) * sizeof(WCHAR);
size = MAX_COMPUTERNAME_LENGTH + 1;
GetComputerNameW(lmAuth.workstationW, &size);
- lmAuth.lmlogon.Workstation.Length = wcslen(lmAuth.workstationW) * sizeof(WCHAR);
+ lmAuth.lmlogon.Workstation.Length = (USHORT)(wcslen(lmAuth.workstationW) * sizeof(WCHAR));
memcpy(lmAuth.lmlogon.ChallengeToClient, vcp->encKey, MSV1_0_CHALLENGE_LENGTH);
lmAuth.tgroups.Groups[0].Sid = NULL;
lmAuth.tgroups.Groups[0].Attributes = 0;
- lmAuth.tsource.SourceIdentifier.HighPart = 0;
- lmAuth.tsource.SourceIdentifier.LowPart = (DWORD) vcp;
+ lmAuth.tsource.SourceIdentifier.HighPart = (DWORD)((LONG_PTR)vcp << 32);
+ lmAuth.tsource.SourceIdentifier.LowPart = (DWORD)((LONG_PTR)vcp & _UI32_MAX);
strcpy(lmAuth.tsource.SourceName,"OpenAFS"); /* 8 char limit */
nts = LsaLogonUser( smb_lsaHandle,
return 0;
}
-/* When using SMB auth, all SMB sessions have to pass through here first to
- * authenticate the user.
- * Caveat: If not use the SMB auth the protocol does not require sending a
- * session setup packet, which means that we can't rely on a UID in subsequent
- * packets. Though in practice we get one anyway.
+/* When using SMB auth, all SMB sessions have to pass through here
+ * first to authenticate the user.
+ *
+ * Caveat: If not using SMB auth, the protocol does not require
+ * sending a session setup packet, which means that we can't rely on a
+ * UID in subsequent packets. Though in practice we get one anyway.
*/
long smb_ReceiveV3SessionSetupX(smb_vc_t *vcp, smb_packet_t *inp, smb_packet_t *outp)
{
if (uidp) { /* already there, so don't create a new one */
unp = uidp->unp;
userp = unp->userp;
- newUid = (unsigned short)uidp->userID; /* For some reason these are different types!*/
- osi_LogEvent("AFS smb_ReceiveV3SessionSetupX",NULL,"FindUserByName:Lana[%d],lsn[%d],userid[%d],name[%s]",vcp->lana,vcp->lsn,newUid,osi_LogSaveString(smb_logp, usern));
+ newUid = uidp->userID;
osi_Log3(smb_logp,"smb_ReceiveV3SessionSetupX FindUserByName:Lana[%d],lsn[%d],userid[%d]",vcp->lana,vcp->lsn,newUid);
smb_ReleaseUID(uidp);
}
uidp = smb_FindUID(vcp, newUid, SMB_FLAG_CREATE);
lock_ObtainMutex(&uidp->mx);
uidp->unp = unp;
- osi_LogEvent("AFS smb_ReceiveV3SessionSetupX",NULL,"MakeNewUser:VCP[%x],Lana[%d],lsn[%d],userid[%d],TicketKTCName[%s]",(int)vcp,vcp->lana,vcp->lsn,newUid,osi_LogSaveString(smb_logp, usern));
- osi_Log4(smb_logp,"smb_ReceiveV3SessionSetupX MakeNewUser:VCP[%x],Lana[%d],lsn[%d],userid[%d]",vcp,vcp->lana,vcp->lsn,newUid);
+ osi_Log4(smb_logp,"smb_ReceiveV3SessionSetupX MakeNewUser:VCP[%p],Lana[%d],lsn[%d],userid[%d]",vcp,vcp->lana,vcp->lsn,newUid);
lock_ReleaseMutex(&uidp->mx);
smb_ReleaseUID(uidp);
}
/* find the tree and free it */
uidp = smb_FindUID(vcp, ((smb_t *)inp)->uid, 0);
- /* TODO: smb_ReleaseUID() ? */
if (uidp) {
char *s1 = NULL, *s2 = NULL;
* because the vcp points to it
*/
lock_ReleaseMutex(&uidp->mx);
+ smb_ReleaseUID(uidp);
}
else
osi_Log0(smb_logp, "SMB3 user logoffX");
tp = malloc(sizeof(*tp));
memset(tp, 0, sizeof(*tp));
- tp->vcp = NULL;
+ smb_HoldVC(vcp);
+ tp->vcp = vcp;
tp->curData = tp->curParms = 0;
tp->totalData = totalData;
tp->totalParms = totalParms;
/* We sometimes see 0 word count. What to do? */
if (*inp->wctp == 0) {
+ osi_Log0(smb_logp, "Transaction2 word count = 0");
#ifndef DJGPP
- HANDLE h;
- char *ptbuf[1];
-
- osi_Log0(smb_logp, "TRANSACTION word count = 0");
-
- h = RegisterEventSource(NULL, AFS_DAEMON_EVENT_NAME);
- ptbuf[0] = "Transaction2 word count = 0";
- ReportEvent(h, EVENTLOG_WARNING_TYPE, 0, 1003, NULL,
- 1, inp->ncb_length, ptbuf, inp);
- DeregisterEventSource(h);
-#else /* DJGPP */
- osi_Log0(smb_logp, "TRANSACTION word count = 0");
+ LogEvent(EVENTLOG_WARNING_TYPE, MSG_SMB_ZERO_TRANSACTION_COUNT);
#endif /* !DJGPP */
smb_SetSMBDataLength(outp, 0);
rapOp = asp->parmsp[0];
if ( rapOp >= 0 && rapOp < SMB_RAP_NOPCODES && smb_rapDispatchTable[rapOp].procp) {
- osi_LogEvent("AFS-Dispatch-RAP[%s]",myCrt_RapDispatch(rapOp),"vcp[%x] lana[%d] lsn[%d]",(int)vcp,vcp->lana,vcp->lsn);
- osi_Log4(smb_logp,"AFS Server - Dispatch-RAP %s vcp[%x] lana[%d] lsn[%d]",myCrt_RapDispatch(rapOp),vcp,vcp->lana,vcp->lsn);
+ osi_Log4(smb_logp,"AFS Server - Dispatch-RAP %s vcp[%p] lana[%d] lsn[%d]",myCrt_RapDispatch(rapOp),vcp,vcp->lana,vcp->lsn);
code = (*smb_rapDispatchTable[rapOp].procp)(vcp, asp, outp);
+ osi_Log4(smb_logp,"AFS Server - Dispatch-RAP return code 0x%x vcp[%x] lana[%d] lsn[%d]",code,vcp,vcp->lana,vcp->lsn);
}
else {
- osi_LogEvent("AFS-Dispatch-RAP [invalid]", NULL, "op[%x] vcp[%x] lana[%d] lsn[%d]", rapOp, vcp, vcp->lana, vcp->lsn);
- osi_Log4(smb_logp,"AFS Server - Dispatch-RAP [INVALID] op[%x] vcp[%x] lana[%d] lsn[%d]", rapOp, vcp, vcp->lana, vcp->lsn);
+ osi_Log4(smb_logp,"AFS Server - Dispatch-RAP [INVALID] op[%x] vcp[%p] lana[%d] lsn[%d]", rapOp, vcp, vcp->lana, vcp->lsn);
code = CM_ERROR_BADOP;
}
cm_ReleaseUser(userp);
- nShares = rootShares.cShare + nRegShares + allSubmount;
+ nShares = (USHORT)(rootShares.cShare + nRegShares + allSubmount);
#define REMARK_LEN 1
outParmsTotal = 8; /* 4 dwords */
if (allSubmount) {
strcpy( shares[cshare].shi1_netname, "all" );
- shares[cshare].shi1_remark = cstrp - outp->datap;
+ shares[cshare].shi1_remark = (DWORD)(cstrp - outp->datap);
/* type and pad are zero already */
cshare++;
cstrp+=REMARK_LEN;
if (rv == ERROR_SUCCESS && strlen(thisShare) && (!allSubmount || stricmp(thisShare,"all"))) {
strncpy(shares[cshare].shi1_netname, thisShare, sizeof(shares->shi1_netname)-1);
shares[cshare].shi1_netname[sizeof(shares->shi1_netname)-1] = 0; /* unfortunate truncation */
- shares[cshare].shi1_remark = cstrp - outp->datap;
+ shares[cshare].shi1_remark = (DWORD)(cstrp - outp->datap);
cshare++;
cstrp+=REMARK_LEN;
}
}
strcpy(shares[cshare].shi1_netname, rootShares.shares[i].shi0_netname);
- shares[cshare].shi1_remark = cstrp - outp->datap;
+ shares[cshare].shi1_remark = (DWORD)(cstrp - outp->datap);
cshare++;
cstrp+=REMARK_LEN;
}
outp->parmsp[2] = cshare;
outp->parmsp[3] = nShares;
- outp->totalData = cstrp - outp->datap;
+ outp->totalData = (int)(cstrp - outp->datap);
outp->totalParms = outParmsTotal;
smb_SendTran2Packet(vcp, outp, op);
smb_rap_share_info_1_t * info = (smb_rap_share_info_1_t *) outp->datap;
strncpy(info->shi1_netname, shareName, sizeof(info->shi1_netname)-1);
info->shi1_netname[sizeof(info->shi1_netname)-1] = 0;
- info->shi1_remark = ((unsigned char *) (info + 1)) - outp->datap;
+ info->shi1_remark = (DWORD)(((unsigned char *) (info + 1)) - outp->datap);
/* type and pad are already zero */
} else { /* infoLevel==2 */
smb_rap_share_info_2_t * info = (smb_rap_share_info_2_t *) outp->datap;
strncpy(info->shi2_netname, shareName, sizeof(info->shi2_netname)-1);
info->shi2_netname[sizeof(info->shi2_netname)-1] = 0;
- info->shi2_remark = ((unsigned char *) (info + 1)) - outp->datap;
+ info->shi2_remark = (DWORD)(((unsigned char *) (info + 1)) - outp->datap);
info->shi2_permissions = ACCESS_ALL;
info->shi2_max_uses = (unsigned short) -1;
- info->shi2_path = 1 + (((unsigned char *) (info + 1)) - outp->datap);
+ info->shi2_path = (DWORD)(1 + (((unsigned char *) (info + 1)) - outp->datap));
}
outp->totalData = totalData;
cstrp += smb_ServerCommentLen;
}
- totalData = cstrp - outp->datap;
+ totalData = (DWORD)(cstrp - outp->datap);
outp->totalData = min(bufsize,totalData); /* actual data size */
outp->parmsp[0] = (outp->totalData == totalData)? 0 : ERROR_MORE_DATA;
outp->parmsp[2] = totalData;
/* We sometimes see 0 word count. What to do? */
if (*inp->wctp == 0) {
+ osi_Log0(smb_logp, "Transaction2 word count = 0");
#ifndef DJGPP
- HANDLE h;
- char *ptbuf[1];
-
- osi_Log0(smb_logp, "TRANSACTION2 word count = 0");
-
- h = RegisterEventSource(NULL, AFS_DAEMON_EVENT_NAME);
- ptbuf[0] = "Transaction2 word count = 0";
- ReportEvent(h, EVENTLOG_WARNING_TYPE, 0, 1003, NULL,
- 1, inp->ncb_length, ptbuf, inp);
- DeregisterEventSource(h);
-#else /* DJGPP */
- osi_Log0(smb_logp, "TRANSACTION2 word count = 0");
+ LogEvent(EVENTLOG_WARNING_TYPE, MSG_SMB_ZERO_TRANSACTION_COUNT);
#endif /* !DJGPP */
smb_SetSMBDataLength(outp, 0);
/* now dispatch it */
if ( asp->opcode >= 0 && asp->opcode < 20 && smb_tran2DispatchTable[asp->opcode].procp) {
- osi_LogEvent("AFS-Dispatch-2[%s]",myCrt_2Dispatch(asp->opcode),"vcp[%x] lana[%d] lsn[%d]",(int)vcp,vcp->lana,vcp->lsn);
- osi_Log4(smb_logp,"AFS Server - Dispatch-2 %s vcp[%x] lana[%d] lsn[%d]",myCrt_2Dispatch(asp->opcode),vcp,vcp->lana,vcp->lsn);
+ osi_Log4(smb_logp,"AFS Server - Dispatch-2 %s vcp[%p] lana[%d] lsn[%d]",myCrt_2Dispatch(asp->opcode),vcp,vcp->lana,vcp->lsn);
code = (*smb_tran2DispatchTable[asp->opcode].procp)(vcp, asp, outp);
}
else {
- osi_LogEvent("AFS-Dispatch-2 [invalid]", NULL, "op[%x] vcp[%x] lana[%d] lsn[%d]", asp->opcode, vcp, vcp->lana, vcp->lsn);
- osi_Log4(smb_logp,"AFS Server - Dispatch-2 [INVALID] op[%x] vcp[%x] lana[%d] lsn[%d]", asp->opcode, vcp, vcp->lana, vcp->lsn);
+ osi_Log4(smb_logp,"AFS Server - Dispatch-2 [INVALID] op[%x] vcp[%p] lana[%d] lsn[%d]", asp->opcode, vcp, vcp->lana, vcp->lsn);
code = CM_ERROR_BADOP;
}
/* save a pointer to the vnode */
fidp->scp = scp;
+ /* and the user */
+ cm_HoldUser(userp);
+ fidp->userp = userp;
/* compute open mode */
if (openMode != 1) fidp->flags |= SMB_FID_OPENREAD;
name = fidp->NTopen_wholepathp;
else
name = "\\"; /* probably can't happen */
- len = strlen(name);
+ len = (unsigned long)strlen(name);
outp->totalData = (len*2) + 4; /* this is actually what we want to return */
*((u_long *)op) = len * 2; op += 4;
mbstowcs((unsigned short *)op, name, len); op += (len * 2);
char requestFileName[1024] = "";
smb_tran2Packet_t *outp = 0;
cm_user_t *userp = 0;
- cm_scache_t *scp;
cm_req_t req;
CPINFO CodePageInfo;
int i, nbnLen, reqLen;
while (*name) {
switch (*pattern) {
case '?':
- if (*name == '.')
- return FALSE;
- ++pattern, ++name;
+ ++pattern;
+ if (*name == '.')
+ continue;
+ ++name;
break;
case '*':
++pattern;
} /* endswitch */
} /* endwhile */
- if (*pattern == '\0' || *pattern == '*' && *(pattern+1) == '\0')
- return TRUE;
- else
- return FALSE;
+ /* if all we have left are wildcards, then we match */
+ for (;*pattern; pattern++) {
+ if (*pattern != '*' && *pattern != '?')
+ return FALSE;
+ }
+ return TRUE;
}
/* do a case-folding search of the star name mask with the name in namep.
if ((dsp->flags & SMB_DIRSEARCH_BULKST) &&
LargeIntegerGreaterThanOrEqualTo(thyper, scp->bulkStatProgress)) {
/* Don't bulk stat if risking timeout */
- int now = GetCurrentTime();
+ int now = GetTickCount();
if (now - req.startTime > 5000) {
scp->bulkStatProgress = thyper;
scp->flags &= ~CM_SCACHEFLAG_BULKSTATTING;
strcpy(op + 70, shortName);
if (smb_StoreAnsiFilenames)
CharToOem(op + 70, op + 70);
- *(op + 68) = shortNameEnd - shortName;
+ *(op + 68) = (char)(shortNameEnd - shortName);
}
}
scp = NULL;
- extraInfo = (smb_GetSMBParm(inp, 2) & 1); /* return extra info */
- openFun = smb_GetSMBParm(inp, 8); /* open function */
+ extraInfo = (smb_GetSMBParm(inp, 2) & 1); /* return extra info */
+ openFun = smb_GetSMBParm(inp, 8); /* open function */
excl = ((openFun & 3) == 0);
- trunc = ((openFun & 3) == 2); /* truncate it */
+ trunc = ((openFun & 3) == 2); /* truncate it */
openMode = (smb_GetSMBParm(inp, 3) & 0x7);
- openAction = 0; /* tracks what we did */
+ openAction = 0; /* tracks what we did */
attributes = smb_GetSMBParm(inp, 5);
dosTime = smb_GetSMBParm(inp, 6) | (smb_GetSMBParm(inp, 7) << 16);
- /* compute initial mode bits based on read-only flag in attributes */
+ /* compute initial mode bits based on read-only flag in attributes */
initialModeBits = 0666;
if (attributes & 1) initialModeBits &= ~0222;
/* save a pointer to the vnode */
fidp->scp = scp;
+ /* also the user */
+ cm_HoldUser(userp);
+ fidp->userp = userp;
/* compute open mode */
if (openMode != 1)
return 0;
}
+static void smb_GetLockParams(unsigned char LockType,
+ char ** buf,
+ unsigned int * ppid,
+ LARGE_INTEGER * pOffset,
+ LARGE_INTEGER * pLength)
+{
+ if (LockType & LOCKING_ANDX_LARGE_FILES) {
+ /* Large Files */
+ *ppid = *((USHORT *) *buf);
+ pOffset->HighPart = *((LONG *)(*buf + 4));
+ pOffset->LowPart = *((DWORD *)(*buf + 8));
+ pLength->HighPart = *((LONG *)(*buf + 12));
+ pLength->LowPart = *((DWORD *)(*buf + 16));
+ *buf += 20;
+ }
+ else {
+ /* Not Large Files */
+ *ppid = *((USHORT *) *buf);
+ pOffset->HighPart = 0;
+ pOffset->LowPart = *((DWORD *)(*buf + 2));
+ pLength->HighPart = 0;
+ pLength->LowPart = *((DWORD *)(*buf + 6));
+ *buf += 10;
+ }
+}
+
long smb_ReceiveV3LockingX(smb_vc_t *vcp, smb_packet_t *inp, smb_packet_t *outp)
{
cm_req_t req;
cm_scache_t *scp;
unsigned char LockType;
unsigned short NumberOfUnlocks, NumberOfLocks;
- unsigned long Timeout;
+ long Timeout;
char *op;
+ char *op_locks;
LARGE_INTEGER LOffset, LLength;
- smb_waitingLock_t *waitingLock;
- void *lockp;
+ smb_waitingLockRequest_t *wlRequest = NULL;
+ cm_file_lock_t *lockp;
long code = 0;
int i;
+ cm_key_t key;
+ unsigned int pid;
cm_InitReq(&req);
fidp = smb_FindFID(vcp, fid, 0);
if (!fidp || (fidp->flags & SMB_FID_IOCTL)) {
+ osi_Log0(smb_logp, "smb_ReceiveV3Locking BadFD");
return CM_ERROR_BADFD;
}
/* set inp->fid so that later read calls in same msg can find fid */
CM_SCACHESYNC_NEEDCALLBACK
| CM_SCACHESYNC_GETSTATUS
| CM_SCACHESYNC_LOCK);
- if (code)
+ if (code) {
+ osi_Log1(smb_logp, "smb_ReceiveV3Locking SyncOp failure code 0x%x", code);
goto doneSync;
+ }
LockType = smb_GetSMBParm(inp, 3) & 0xff;
Timeout = (smb_GetSMBParm(inp, 5) << 16) + smb_GetSMBParm(inp, 4);
NumberOfUnlocks = smb_GetSMBParm(inp, 6);
NumberOfLocks = smb_GetSMBParm(inp, 7);
+ if ((LockType & LOCKING_ANDX_CANCEL_LOCK) ||
+ (LockType & LOCKING_ANDX_CHANGE_LOCKTYPE)) {
+
+ /* We don't support these requests. Apparently, we can safely
+ not deal with them too. */
+ osi_Log1(smb_logp, "smb_ReceiveV3Locking received unsupported request [%s]",
+ ((LockType & LOCKING_ANDX_CANCEL_LOCK)?
+ "LOCKING_ANDX_CANCEL_LOCK":
+ "LOCKING_ANDX_CHANGE_LOCKTYPE"));
+ /* No need to call osi_LogSaveString since these are string
+ constants.*/
+
+ code = CM_ERROR_BADOP;
+ goto done;
+
+ }
+
op = smb_GetSMBData(inp, NULL);
for (i=0; i<NumberOfUnlocks; i++) {
- if (LockType & LOCKING_ANDX_LARGE_FILES) {
- /* Large Files */
- LOffset.HighPart = *((LONG *)(op + 4));
- LOffset.LowPart = *((DWORD *)(op + 8));
- LLength.HighPart = *((LONG *)(op + 12));
- LLength.LowPart = *((DWORD *)(op + 16));
- op += 20;
- }
- else {
- /* Not Large Files */
- LOffset.HighPart = 0;
- LOffset.LowPart = *((DWORD *)(op + 2));
- LLength.HighPart = 0;
- LLength.LowPart = *((DWORD *)(op + 6));
- op += 10;
- }
- if (LargeIntegerNotEqualToZero(LOffset))
- continue;
- /* Do not check length -- length check done in cm_Unlock */
+ smb_GetLockParams(LockType, &op, &pid, &LOffset, &LLength);
- code = cm_Unlock(scp, LockType, LOffset, LLength, userp, &req);
- if (code) goto done;
- }
+ key = cm_GenerateKey(vcp->vcID, pid, fidp->fid);
+
+ code = cm_Unlock(scp, LockType, LOffset, LLength, key, userp, &req);
+
+ if (code)
+ goto done;
+ }
+
+ op_locks = op;
for (i=0; i<NumberOfLocks; i++) {
- if (LockType & LOCKING_ANDX_LARGE_FILES) {
- /* Large Files */
- LOffset.HighPart = *((LONG *)(op + 4));
- LOffset.LowPart = *((DWORD *)(op + 8));
- LLength.HighPart = *((LONG *)(op + 12));
- LLength.LowPart = *((DWORD *)(op + 16));
- op += 20;
- }
- else {
- /* Not Large Files */
- LOffset.HighPart = 0;
- LOffset.LowPart = *((DWORD *)(op + 2));
- LLength.HighPart = 0;
- LLength.LowPart = *((DWORD *)(op + 6));
- op += 10;
- }
- if (LargeIntegerNotEqualToZero(LOffset))
- continue;
- if (LargeIntegerLessThan(LOffset, scp->length))
- continue;
+ smb_GetLockParams(LockType, &op, &pid, &LOffset, &LLength);
- code = cm_Lock(scp, LockType, LOffset, LLength, Timeout,
+ key = cm_GenerateKey(vcp->vcID, pid, fidp->fid);
+
+ code = cm_Lock(scp, LockType, LOffset, LLength, key, (Timeout != 0),
userp, &req, &lockp);
+
if (code == CM_ERROR_WOULDBLOCK && Timeout != 0) {
+ smb_waitingLock_t * wLock;
+
/* Put on waiting list */
- waitingLock = malloc(sizeof(smb_waitingLock_t));
- waitingLock->vcp = vcp;
- smb_HoldVC(vcp);
- waitingLock->inp = smb_CopyPacket(inp);
- waitingLock->outp = smb_CopyPacket(outp);
- waitingLock->timeRemaining = Timeout;
- waitingLock->lockp = lockp;
+ if(wlRequest == NULL) {
+ int j;
+ char * opt;
+ cm_key_t tkey;
+ LARGE_INTEGER tOffset, tLength;
+
+ wlRequest = malloc(sizeof(smb_waitingLockRequest_t));
+
+ osi_assert(wlRequest != NULL);
+
+ wlRequest->vcp = vcp;
+ smb_HoldVC(vcp);
+ wlRequest->scp = scp;
+ cm_HoldSCache(scp);
+ wlRequest->inp = smb_CopyPacket(inp);
+ wlRequest->outp = smb_CopyPacket(outp);
+ wlRequest->lockType = LockType;
+ wlRequest->timeRemaining = Timeout;
+ wlRequest->locks = NULL;
+
+ /* The waiting lock request needs to have enough
+ information to undo all the locks in the request.
+ We do the following to store info about locks that
+ have already been granted. Sure, we can get most
+ of the info from the packet, but the packet doesn't
+ hold the result of cm_Lock call. In practice we
+ only receive packets with one or two locks, so we
+ are only wasting a few bytes here and there and
+ only for a limited period of time until the waiting
+ lock times out or is freed. */
+
+ for(opt = op_locks, j=i; j > 0; j--) {
+ smb_GetLockParams(LockType, &opt, &pid, &tOffset, &tLength);
+
+ tkey = cm_GenerateKey(vcp->vcID, pid, fidp->fid);
+
+ wLock = malloc(sizeof(smb_waitingLock_t));
+
+ osi_assert(wLock != NULL);
+
+ wLock->key = tkey;
+ wLock->LOffset = tOffset;
+ wLock->LLength = tLength;
+ wLock->lockp = NULL;
+ wLock->state = SMB_WAITINGLOCKSTATE_DONE;
+ osi_QAdd((osi_queue_t **) &wlRequest->locks,
+ &wLock->q);
+ }
+ }
+
+ wLock = malloc(sizeof(smb_waitingLock_t));
+
+ osi_assert(wLock != NULL);
+
+ wLock->key = key;
+ wLock->LOffset = LOffset;
+ wLock->LLength = LLength;
+ wLock->lockp = lockp;
+ wLock->state = SMB_WAITINGLOCKSTATE_WAITING;
+ osi_QAdd((osi_queue_t **) &wlRequest->locks,
+ &wLock->q);
+
+ osi_Log1(smb_logp, "smb_ReceiveV3Locking WaitingLock created 0x%p",
+ wLock);
+
+ code = 0;
+ continue;
+ }
+
+ if (code) {
+ osi_Log1(smb_logp, "smb_ReceiveV3Locking cm_Lock failure code 0x%x", code);
+ break;
+ }
+ }
+
+ if (code) {
+
+ /* Since something went wrong with the lock number i, we now
+ have to go ahead and release any locks acquired before the
+ failure. All locks before lock number i (of which there
+ are i of them) have either been successful or are waiting.
+ Either case requires calling cm_Unlock(). */
+
+ /* And purge the waiting lock */
+ if(wlRequest != NULL) {
+ smb_waitingLock_t * wl;
+ smb_waitingLock_t * wlNext;
+ long ul_code;
+
+ for(wl = wlRequest->locks; wl; wl = wlNext) {
+
+ wlNext = (smb_waitingLock_t *) osi_QNext(&wl->q);
+
+ ul_code = cm_Unlock(scp, LockType, wl->LOffset, wl->LLength, wl->key, userp, &req);
+
+ if(ul_code != 0) {
+ osi_Log1(smb_logp, "smb_ReceiveV3Locking cm_Unlock returns code %d", ul_code);
+ } else {
+ osi_Log0(smb_logp, "smb_ReceiveV3Locking cm_Unlock successful");
+ }
+
+ osi_QRemove((osi_queue_t **) &wlRequest->locks, &wl->q);
+ free(wl);
+
+ }
+
+ smb_ReleaseVC(wlRequest->vcp);
+ cm_ReleaseSCache(wlRequest->scp);
+ smb_FreePacket(wlRequest->inp);
+ smb_FreePacket(wlRequest->outp);
+
+ free(wlRequest);
+
+ wlRequest = NULL;
+ }
+
+ } else {
+
+ if (wlRequest != NULL) {
+
lock_ObtainWrite(&smb_globalLock);
osi_QAdd((osi_queue_t **)&smb_allWaitingLocks,
- &waitingLock->q);
- osi_Wakeup((long) &smb_allWaitingLocks);
+ &wlRequest->q);
+ osi_Wakeup((LONG_PTR)&smb_allWaitingLocks);
lock_ReleaseWrite(&smb_globalLock);
+
/* don't send reply immediately */
outp->flags |= SMB_PACKETFLAG_NOSEND;
}
- if (code)
- break;
- }
- if (code) {
- /* release any locks acquired before the failure */
- }
- else
smb_SetSMBDataLength(outp, 0);
+ }
+
done:
cm_SyncOpDone(scp, NULL, CM_SCACHESYNC_LOCK);
+
doneSync:
lock_ReleaseMutex(&scp->mx);
cm_ReleaseUser(userp);
long smb_ReceiveV3ReadX(smb_vc_t *vcp, smb_packet_t *inp, smb_packet_t *outp)
{
osi_hyper_t offset;
- long count, finalCount;
+ long count;
+ long finalCount = 0;
unsigned short fd;
+ unsigned pid;
smb_fid_t *fidp;
long code = 0;
cm_user_t *userp;
+ cm_key_t key;
char *op;
fd = smb_GetSMBParm(inp, 2);
if (!fidp) {
return CM_ERROR_BADFD;
}
+
+ pid = ((smb_t *) inp)->pid;
+ key = cm_GenerateKey(vcp->vcID, pid, fd);
+ {
+ LARGE_INTEGER LOffset, LLength;
+
+ LOffset.HighPart = offset.HighPart;
+ LOffset.LowPart = offset.LowPart;
+ LLength.HighPart = 0;
+ LLength.LowPart = count;
+
+ lock_ObtainMutex(&fidp->scp->mx);
+ code = cm_LockCheckRead(fidp->scp, LOffset, LLength, key);
+ lock_ReleaseMutex(&fidp->scp->mx);
+ }
+
+ if (code) {
+ smb_ReleaseFID(fidp);
+ return code;
+ }
+
/* set inp->fid so that later read calls in same msg can find fid */
inp->fid = fd;
if (fidp->flags & SMB_FID_IOCTL) {
return smb_IoctlV3Read(fidp, vcp, inp, outp);
}
-
+
userp = smb_GetUser(vcp, inp);
/* 0 and 1 are reserved for request chaining, were setup by our caller,
unsigned int extAttributes;
unsigned int createDisp;
unsigned int createOptions;
+ unsigned int shareAccess;
int initialModeBits;
unsigned short baseFid;
smb_fid_t *baseFidp;
| (smb_GetSMBOffsetParm(inp, 8, 1) << 16);
extAttributes = smb_GetSMBOffsetParm(inp, 13, 1)
| (smb_GetSMBOffsetParm(inp, 14, 1) << 16);
+ shareAccess = smb_GetSMBOffsetParm(inp, 15, 1)
+ | (smb_GetSMBOffsetParm(inp, 16, 1) << 16);
createDisp = smb_GetSMBOffsetParm(inp, 17, 1)
| (smb_GetSMBOffsetParm(inp, 18, 1) << 16);
createOptions = smb_GetSMBOffsetParm(inp, 19, 1)
* extended attributes
*/
initialModeBits = 0666;
- if (extAttributes & 1)
+ if (extAttributes & SMB_ATTR_READONLY)
initialModeBits &= ~0222;
pathp = smb_GetSMBData(inp, NULL);
osi_Log1(smb_logp,"NTCreateX for [%s]",osi_LogSaveString(smb_logp,realPathp));
osi_Log4(smb_logp,"... da=[%x] ea=[%x] cd=[%x] co=[%x]", desiredAccess, extAttributes, createDisp, createOptions);
- osi_Log2(smb_logp,"... flags=[%x] lastNamep=[%s]", flags, osi_LogSaveString(smb_logp,(lastNamep?lastNamep:"null")));
+ osi_Log3(smb_logp,"... share=[%x] flags=[%x] lastNamep=[%s]", shareAccess, flags, osi_LogSaveString(smb_logp,(lastNamep?lastNamep:"null")));
if (lastNamep && strcmp(lastNamep, SMB_IOCTL_FILENAME) == 0) {
/* special case magic file name for receiving IOCTL requests
free(hexp);
}
#endif
+
userp = smb_GetUser(vcp, inp);
if (!userp) {
osi_Log1(smb_logp, "NTCreateX Invalid user [%d]", ((smb_t *) inp)->uid);
fidflags |= SMB_FID_OPENREAD;
if (desiredAccess & AFS_ACCESS_WRITE)
fidflags |= SMB_FID_OPENWRITE;
+ if (createOptions & FILE_DELETE_ON_CLOSE)
+ fidflags |= SMB_FID_DELONCLOSE;
+
+ /* and the share mode */
+ if (shareAccess & FILE_SHARE_READ)
+ fidflags |= SMB_FID_SHARE_READ;
+ if (shareAccess & FILE_SHARE_WRITE)
+ fidflags |= SMB_FID_SHARE_WRITE;
code = 0;
/* we have scp but not dscp */
if (baseFid != 0)
smb_ReleaseFID(baseFidp);
- }
+ }
/* if we get here, if code is 0, the file exists and is represented by
* scp. Otherwise, we have to create it. The dir may be represented
* scp is NULL.
*/
if (code == 0 && !treeCreate) {
- if (createDisp == FILE_CREATE) {
+ code = cm_CheckNTOpen(scp, desiredAccess, createDisp, userp, &req);
+ if (code) {
+ if (dscp)
+ cm_ReleaseSCache(dscp);
+ if (scp)
+ cm_ReleaseSCache(scp);
+ cm_ReleaseUser(userp);
+ free(realPathp);
+ return code;
+ }
+
+ if (createDisp == FILE_CREATE) {
/* oops, file shouldn't be there */
if (dscp)
cm_ReleaseSCache(dscp);
if ( createDisp == FILE_OVERWRITE ||
createDisp == FILE_OVERWRITE_IF) {
+
setAttr.mask = CM_ATTRMASK_LENGTH;
setAttr.length.LowPart = 0;
setAttr.length.HighPart = 0;
else
openAction = 1; /* found existing file */
- code = cm_CheckNTOpen(scp, desiredAccess, createDisp, userp, &req);
- if (code) {
- if (dscp)
- cm_ReleaseSCache(dscp);
- if (scp)
- cm_ReleaseSCache(scp);
- cm_ReleaseUser(userp);
- free(realPathp);
- return code;
- }
} else if (createDisp == FILE_OPEN || createDisp == FILE_OVERWRITE) {
/* don't create if not found */
if (dscp)
osi_LogSaveString(smb_logp, treeStartp));
openAction = 2; /* created directory */
+ /* if the request is to create the root directory
+ * it will appear as a directory name of the nul-string
+ * and a code of CM_ERROR_NOSUCHFILE
+ */
+ if ( !*treeStartp && code == CM_ERROR_NOSUCHFILE)
+ code = CM_ERROR_EXISTS;
+
setAttr.mask = CM_ATTRMASK_CLIENTMODTIME;
setAttr.clientModTime = time(NULL);
tp = strchr(pp, '\\');
if (!tp) {
strcpy(cp,pp);
- clen = strlen(cp);
+ clen = (int)strlen(cp);
isLast = 1; /* indicate last component. the supplied path never ends in a slash */
} else {
- clen = tp - pp;
+ clen = (int)(tp - pp);
strncpy(cp,pp,clen);
*(cp + clen) = 0;
tp++;
/* open the file itself */
fidp = smb_FindFID(vcp, 0, SMB_FLAG_CREATE);
osi_assert(fidp);
+
+ /* save a reference to the user */
+ cm_HoldUser(userp);
+ fidp->userp = userp;
+
+ /* If we are restricting sharing, we should do so with a suitable
+ share lock. */
+ if (scp->fileType == CM_SCACHETYPE_FILE &&
+ !(fidflags & SMB_FID_SHARE_WRITE)) {
+ cm_key_t key;
+ LARGE_INTEGER LOffset, LLength;
+ int sLockType;
+
+ LOffset.HighPart = SMB_FID_QLOCK_HIGH;
+ LOffset.LowPart = SMB_FID_QLOCK_LOW;
+ LLength.HighPart = 0;
+ LLength.LowPart = SMB_FID_QLOCK_LENGTH;
+
+ if (fidflags & SMB_FID_SHARE_READ) {
+ sLockType = LOCKING_ANDX_SHARED_LOCK;
+ } else {
+ sLockType = 0;
+ }
+
+ key = cm_GenerateKey(vcp->vcID, SMB_FID_QLOCK_PID, fidp->fid);
+
+ lock_ObtainMutex(&scp->mx);
+ code = cm_Lock(scp, sLockType, LOffset, LLength, key, 0, userp, &req, NULL);
+ lock_ReleaseMutex(&scp->mx);
+
+ if (code) {
+ fidp->flags = SMB_FID_DELETE;
+ smb_ReleaseFID(fidp);
+
+ cm_ReleaseSCache(scp);
+ if (dscp)
+ cm_ReleaseSCache(dscp);
+ cm_ReleaseUser(userp);
+ free(realPathp);
+
+ return code;
+ }
+ }
+
/* save a pointer to the vnode */
fidp->scp = scp; /* Hold transfered to fidp->scp and no longer needed */
cm_ReleaseSCache(dscp);
dscp = NULL;
}
+
cm_Open(scp, 0, userp);
/* set inp->fid so that later read calls in same msg can find fid */
cm_ReleaseUser(userp);
- /* Can't free realPathp if we get here since fidp->NTopen_wholepathp is pointing there */
+ /* Can't free realPathp if we get here since
+ fidp->NTopen_wholepathp is pointing there */
/* leave scp held since we put it in fidp->scp */
return 0;
unsigned int desiredAccess;
#ifdef DEBUG_VERBOSE
unsigned int allocSize;
- unsigned int shareAccess;
#endif
+ unsigned int shareAccess;
unsigned int extAttributes;
unsigned int createDisp;
#ifdef DEBUG_VERBOSE
allocSize = lparmp[3];
#endif /* DEBUG_VERSOSE */
extAttributes = lparmp[5];
-#ifdef DEBUG_VEROSE
shareAccess = lparmp[6];
-#endif
createDisp = lparmp[7];
createOptions = lparmp[8];
#ifdef DEBUG_VERBOSE
fidflags |= SMB_FID_OPENREAD;
if (desiredAccess & AFS_ACCESS_WRITE)
fidflags |= SMB_FID_OPENWRITE;
+ if (createOptions & FILE_DELETE_ON_CLOSE)
+ fidflags |= SMB_FID_DELONCLOSE;
+
+ /* And the share mode */
+ if (shareAccess & FILE_SHARE_READ)
+ fidflags |= SMB_FID_SHARE_READ;
+ if (shareAccess & FILE_SHARE_WRITE)
+ fidflags |= SMB_FID_SHARE_WRITE;
dscp = NULL;
code = 0;
fidp = smb_FindFID(vcp, 0, SMB_FLAG_CREATE);
osi_assert(fidp);
+ /* save a reference to the user */
+ cm_HoldUser(userp);
+ fidp->userp = userp;
+
+ /* If we are restricting sharing, we should do so with a suitable
+ share lock. */
+ if (scp->fileType == CM_SCACHETYPE_FILE &&
+ !(fidflags & SMB_FID_SHARE_WRITE)) {
+ cm_key_t key;
+ LARGE_INTEGER LOffset, LLength;
+ int sLockType;
+
+ LOffset.HighPart = SMB_FID_QLOCK_HIGH;
+ LOffset.LowPart = SMB_FID_QLOCK_LOW;
+ LLength.HighPart = 0;
+ LLength.LowPart = SMB_FID_QLOCK_LENGTH;
+
+ if (fidflags & SMB_FID_SHARE_READ) {
+ sLockType = LOCKING_ANDX_SHARED_LOCK;
+ } else {
+ sLockType = 0;
+ }
+
+ key = cm_GenerateKey(vcp->vcID, SMB_FID_QLOCK_PID, fidp->fid);
+
+ lock_ObtainMutex(&scp->mx);
+ code = cm_Lock(scp, sLockType, LOffset, LLength, key, 0, userp, &req, NULL);
+ lock_ReleaseMutex(&scp->mx);
+
+ if (code) {
+ fidp->flags = SMB_FID_DELETE;
+ smb_ReleaseFID(fidp);
+
+ cm_ReleaseSCache(scp);
+ cm_ReleaseUser(userp);
+ free(realPathp);
+
+ return CM_ERROR_SHARING_VIOLATION;
+ }
+ }
+
/* save a pointer to the vnode */
fidp->scp = scp;
savedPacketp = smb_CopyPacket(inp);
smb_HoldVC(vcp);
+ if (savedPacketp->vcp)
+ smb_ReleaseVC(savedPacketp->vcp);
savedPacketp->vcp = vcp;
lock_ObtainMutex(&smb_Dir_Watch_Lock);
savedPacketp->nextp = smb_Directory_Watches;
((smb_t *)outp)->flg2 |= SMB_FLAGS2_IS_LONG_NAME;
switch (function) {
- case 6:
- return smb_ReceiveNTTranQuerySecurityDesc(vcp, inp, outp);
- case 4:
- return smb_ReceiveNTTranNotifyChange(vcp, inp, outp);
case 1:
return smb_ReceiveNTTranCreate(vcp, inp, outp);
- default:
- return CM_ERROR_INVAL;
+ case 2:
+ osi_Log0(smb_logp, "SMB NT Transact Ioctl - not implemented");
+ break;
+ case 3:
+ osi_Log0(smb_logp, "SMB NT Transact SetSecurityDesc - not implemented");
+ break;
+ case 4:
+ return smb_ReceiveNTTranNotifyChange(vcp, inp, outp);
+ case 5:
+ osi_Log0(smb_logp, "SMB NT Transact Rename - not implemented");
+ break;
+ case 6:
+ return smb_ReceiveNTTranQuerySecurityDesc(vcp, inp, outp);
}
+ return CM_ERROR_INVAL;
}
/*
BOOL twoEntries = FALSE;
ULONG otherNameLen, oldParmCount = 0;
DWORD otherAction;
- smb_vc_t *vcp;
smb_fid_t *fidp;
/* Get ready for rename within directory */
wtree = smb_GetSMBParm(watch, 22) & 0xffff; /* TODO: should this be 0xff ? */
maxLen = smb_GetSMBOffsetParm(watch, 5, 1)
| (smb_GetSMBOffsetParm(watch, 6, 1) << 16);
- vcp = watch->vcp;
/*
* Strange hack - bug in NT Client and NT Server that we
if (filter == 3 && wtree)
filter = 0x17;
- fidp = smb_FindFID(vcp, fid, 0);
+ fidp = smb_FindFID(watch->vcp, fid, 0);
if (!fidp) {
osi_Log1(smb_logp," no fidp for fid[%d]",fid);
lastWatch = watch;
if (filename == NULL)
parmCount = 0;
else {
- nameLen = strlen(filename);
+ nameLen = (ULONG)strlen(filename);
parmCount = 3*4 + nameLen*2;
parmCount = (parmCount + 3) & ~3; /* pad to 4 */
if (twoEntries) {
- otherNameLen = strlen(otherFilename);
+ otherNameLen = (ULONG)strlen(otherFilename);
oldParmCount = parmCount;
parmCount += 3*4 + otherNameLen*2;
parmCount = (parmCount + 3) & ~3; /* pad to 4 */
((smb_t *) watch)->flg2 |= SMB_FLAGS2_32BIT_STATUS;
}
- smb_SendPacket(vcp, watch);
+ smb_SendPacket(watch->vcp, watch);
smb_FreePacket(watch);
watch = nextWatch;
}
lock_InitializeMutex(&smb_Dir_Watch_Lock, "Directory Watch List Lock");
}
-cm_user_t *smb_FindCMUserByName(/*smb_vc_t *vcp,*/ char *usern, char *machine)
+cm_user_t *smb_FindCMUserByName(char *usern, char *machine)
{
- /*int newUid;*/
smb_username_t *unp;
+ cm_user_t * userp;
unp = smb_FindUserByName(usern, machine, SMB_FLAG_CREATE);
if (!unp->userp) {
unp->userp = cm_NewUser();
lock_ReleaseMutex(&unp->mx);
osi_Log2(smb_logp,"smb_FindCMUserByName New user name[%s] machine[%s]",osi_LogSaveString(smb_logp,usern),osi_LogSaveString(smb_logp,machine));
- osi_LogEvent("AFS smb_FindCMUserByName : New User",NULL,"name[%s] machine[%s]",usern,machine);
} else {
osi_Log2(smb_logp,"smb_FindCMUserByName Not found name[%s] machine[%s]",osi_LogSaveString(smb_logp,usern),osi_LogSaveString(smb_logp,machine));
- osi_LogEvent("AFS smb_FindCMUserByName : Found",NULL,"name[%s] machine[%s]",usern,machine);
- }
- return unp->userp;
+ }
+ userp = unp->userp;
+ cm_HoldUser(userp);
+ smb_ReleaseUsername(unp);
+ return userp;
}