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) {
- up = uidp->unp->userp;
- cm_HoldUser(up);
- }
- lock_ReleaseMutex(&uidp->mx);
+ up = smb_GetUserFromUID(uidp);
smb_ReleaseUID(uidp);
}
void OutputDebugHexDump(unsigned char * buffer, int len) {
- int i,j,k;
+ int i,j,k,pcts=0;
char buf[256];
static char tr[16] = {'0','1','2','3','4','5','6','7','8','9','A','B','C','D','E','F'};
buf[j] = tr[k / 16]; buf[j+1] = tr[k % 16];
j = (i%16);
- j = j + 56 + ((j>7)?1:0);
+ j = j + 56 + ((j>7)?1:0) + pcts;
buf[j] = (k>32 && k<127)?k:'.';
+ if (k == '%') {
+ buf[++j] = k;
+ pcts++;
+ }
}
if(i) {
osi_Log0(smb_logp, osi_LogSaveString(smb_logp, buf));
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,
smb_user_t *uidp;
unsigned short newUid;
unsigned long caps = 0;
- cm_user_t *userp;
smb_username_t *unp;
char *s1 = " ";
long code = 0;
uidp = smb_FindUserByNameThisSession(vcp, usern);
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));
- osi_Log3(smb_logp,"smb_ReceiveV3SessionSetupX FindUserByName:Lana[%d],lsn[%d],userid[%d]",vcp->lana,vcp->lsn,newUid);
+ newUid = uidp->userID;
+ osi_Log3(smb_logp,"smb_ReceiveV3SessionSetupX FindUserByName:Lana[%d],lsn[%d],userid[%d]",
+ vcp->lana,vcp->lsn,newUid);
smb_ReleaseUID(uidp);
}
else {
- /* do a global search for the username/machine name pair */
+ cm_user_t *userp;
+
+ /* do a global search for the username/machine name pair */
unp = smb_FindUserByName(usern, vcp->rname, SMB_FLAG_CREATE);
+ lock_ObtainMutex(&unp->mx);
+ if (unp->flags & SMB_USERNAMEFLAG_AFSLOGON) {
+ /* clear the afslogon flag so that the tickets can now
+ * be freed when the refCount returns to zero.
+ */
+ unp->flags &= ~SMB_USERNAMEFLAG_AFSLOGON;
+ }
+ lock_ReleaseMutex(&unp->mx);
/* Create a new UID and cm_user_t structure */
userp = unp->userp;
if (!userp)
userp = cm_NewUser();
- lock_ObtainMutex(&vcp->mx);
+ cm_HoldUserVCRef(userp);
+ lock_ObtainMutex(&vcp->mx);
if (!vcp->uidCounter)
vcp->uidCounter++; /* handle unlikely wraparounds */
newUid = (strlen(usern)==0)?0:vcp->uidCounter++;
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);
}
{
smb_user_t *uidp;
- /* don't get tokens from this VC */
- vcp->flags |= SMB_VCFLAG_ALREADYDEAD;
-
- inp->flags |= SMB_PACKETFLAG_PROFILE_UPDATE_OK;
-
/* 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;
+ smb_username_t * unp;
- if (s2 == NULL) s2 = " ";
- if (s1 == NULL) {s1 = s2; s2 = " ";}
-
- osi_Log4(smb_logp, "SMB3 user logoffX uid %d name %s%s%s", uidp->userID,
- osi_LogSaveString(smb_logp, (uidp->unp) ? uidp->unp->name: " "),
- osi_LogSaveString(smb_logp,s1), osi_LogSaveString(smb_logp,s2));
+ osi_Log2(smb_logp, "SMB3 user logoffX uid %d name %s", uidp->userID,
+ osi_LogSaveString(smb_logp, (uidp->unp) ? uidp->unp->name: " "));
lock_ObtainMutex(&uidp->mx);
uidp->flags |= SMB_USERFLAG_DELETE;
- /*
+ /*
* it doesn't get deleted right away
* because the vcp points to it
*/
+ unp = uidp->unp;
lock_ReleaseMutex(&uidp->mx);
+
+#ifdef COMMENT
+ /* we can't do this. we get logoff messages prior to a session
+ * disconnect even though it doesn't mean the user is logging out.
+ * we need to create a new pioctl and EventLogoff handler to set
+ * SMB_USERNAMEFLAG_LOGOFF.
+ */
+ if (unp && smb_LogoffTokenTransfer) {
+ lock_ObtainMutex(&unp->mx);
+ unp->flags |= SMB_USERNAMEFLAG_LOGOFF;
+ unp->last_logoff_t = osi_Time() + smb_LogoffTransferTimeout;
+ lock_ReleaseMutex(&unp->mx);
+ }
+#endif
+
+ smb_ReleaseUID(uidp);
}
else
osi_Log0(smb_logp, "SMB3 user logoffX");
#endif
}
- userp = smb_GetUser(vcp, inp);
+ uidp = smb_FindUID(vcp, ((smb_t *)inp)->uid, 0);
+ userp = smb_GetUserFromUID(uidp);
lock_ObtainMutex(&vcp->mx);
newTid = vcp->tidCounter++;
tidp = smb_FindTID(vcp, newTid, SMB_FLAG_CREATE);
if (!ipc) {
- uidp = smb_FindUID(vcp, ((smb_t *)inp)->uid, 0);
+ if (!strcmp(shareName, "*."))
+ strcpy(shareName, "all");
shareFound = smb_FindShare(vcp, uidp, shareName, &sharePath);
- if (uidp)
- smb_ReleaseUID(uidp);
if (!shareFound) {
+ smb_ReleaseUID(uidp);
smb_ReleaseTID(tidp);
return CM_ERROR_BADSHARENAME;
}
smb_SetSMBParm(outp, 2, 0);
sharePath = NULL;
}
+ smb_ReleaseUID(uidp);
lock_ObtainMutex(&tidp->mx);
tidp->userp = userp;
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;
return tp;
}
-/* free a tran2 packet; must be called with smb_globalLock held */
+/* free a tran2 packet */
void smb_FreeTran2Packet(smb_tran2Packet_t *t2p)
{
- if (t2p->vcp)
+ if (t2p->vcp) {
smb_ReleaseVC(t2p->vcp);
+ t2p->vcp = NULL;
+ }
if (t2p->flags & SMB_TRAN2PFLAG_ALLOC) {
if (t2p->parmsp)
free(t2p->parmsp);
/* 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;
}
}
/* free the input tran 2 packet */
- lock_ObtainWrite(&smb_globalLock);
smb_FreeTran2Packet(asp);
- lock_ReleaseWrite(&smb_globalLock);
}
else if (firstPacket) {
/* the first packet in a multi-packet request, we need to send an
int outDataTotal; /* total data bytes */
int code = 0;
DWORD rv;
- DWORD allSubmount;
- USHORT nShares;
- DWORD nRegShares;
- DWORD nSharesRet;
+ DWORD allSubmount = 0;
+ USHORT nShares = 0;
+ DWORD nRegShares = 0;
+ DWORD nSharesRet = 0;
HKEY hkParam;
HKEY hkSubmount = NULL;
smb_rap_share_info_1_t * shares;
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);
outp = smb_GetTran2ResponsePacket(vcp, p, op, totalParam, totalData);
- if(!stricmp(shareName,"all")) {
+ if(!stricmp(shareName,"all") || !strcmp(shareName,"*.")) {
rv = RegOpenKeyEx(HKEY_LOCAL_MACHINE, AFSREG_CLT_SVC_PARAM_SUBKEY, 0,
KEY_QUERY_VALUE, &hkParam);
if (rv == ERROR_SUCCESS) {
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;
}
}
/* free the input tran 2 packet */
- lock_ObtainWrite(&smb_globalLock);
smb_FreeTran2Packet(asp);
- lock_ReleaseWrite(&smb_globalLock);
}
else if (firstPacket) {
/* the first packet in a multi-packet request, we need to send an
long returnEALength;
char *tidPathp;
cm_req_t req;
+ int created = 0;
cm_InitReq(&req);
smb_UnixTimeFromSearchTime(&setAttr.clientModTime, dosTime);
code = cm_Create(dscp, lastNamep, 0, &setAttr, &scp, userp,
&req);
- if (code == 0 && (dscp->flags & CM_SCACHEFLAG_ANYWATCH))
- smb_NotifyChange(FILE_ACTION_ADDED,
- FILE_NOTIFY_CHANGE_FILE_NAME,
- dscp, lastNamep, NULL, TRUE);
- if (!excl && code == CM_ERROR_EXISTS) {
+ if (code == 0) {
+ created = 1;
+ if (dscp->flags & CM_SCACHEFLAG_ANYWATCH)
+ smb_NotifyChange(FILE_ACTION_ADDED,
+ FILE_NOTIFY_CHANGE_FILE_NAME,
+ dscp, lastNamep, NULL, TRUE);
+ } else if (!excl && code == CM_ERROR_EXISTS) {
/* not an exclusive create, and someone else tried
* creating it already, then we open it anyway. We
* don't bother retrying after this, since if this next
fidp = smb_FindFID(vcp, 0, SMB_FLAG_CREATE);
osi_assert(fidp);
+ cm_HoldUser(userp);
+ lock_ObtainMutex(&fidp->mx);
/* save a pointer to the vnode */
fidp->scp = scp;
+ /* and the user */
+ fidp->userp = userp;
/* compute open mode */
- if (openMode != 1) fidp->flags |= SMB_FID_OPENREAD;
+ if (openMode != 1)
+ fidp->flags |= SMB_FID_OPENREAD;
if (openMode == 1 || openMode == 2)
fidp->flags |= SMB_FID_OPENWRITE;
+ /* remember that the file was newly created */
+ if (created)
+ fidp->flags |= SMB_FID_CREATED;
+
+ lock_ReleaseMutex(&fidp->mx);
+
smb_ReleaseFID(fidp);
cm_Open(scp, 0, userp);
switch (p->parmsp[0]) {
case 1: responseSize = sizeof(qi.u.allocInfo); break;
case 2: responseSize = sizeof(qi.u.volumeInfo); break;
+ break;
case 0x102: responseSize = sizeof(qi.u.FSvolumeInfo); break;
case 0x103: responseSize = sizeof(qi.u.FSsizeInfo); break;
case 0x104: responseSize = sizeof(qi.u.FSdeviceInfo); break;
case 0x105: responseSize = sizeof(qi.u.FSattributeInfo); break;
case 0x200: /* CIFS Unix Info */
case 0x301: /* Mac FS Info */
- default: return CM_ERROR_INVAL;
+ default:
+ return CM_ERROR_INVAL;
}
outp = smb_GetTran2ResponsePacket(vcp, p, op, 0, responseSize);
cm_scache_t *scp, *dscp;
long code = 0;
char *op;
+ char *pathp;
char *tidPathp;
char *lastComp;
cm_req_t req;
smb_SendTran2Error(vcp, p, opx, CM_ERROR_INVAL);
return 0;
}
+
+ pathp = (char *)(&p->parmsp[3]);
+ if (smb_StoreAnsiFilenames)
+ OemToChar(pathp,pathp);
osi_Log2(smb_logp, "T2 QPathInfo type 0x%x path %s", infoLevel,
- osi_LogSaveString(smb_logp, (char *)(&p->parmsp[3])));
+ osi_LogSaveString(smb_logp, pathp));
outp = smb_GetTran2ResponsePacket(vcp, p, opx, 2, nbytesRequired);
*/
if (infoLevel == SMB_QUERY_FILE_BASIC_INFO) {
spacep = cm_GetSpace();
- smb_StripLastComponent(spacep->data, &lastComp,
- (char *)(&p->parmsp[3]));
+ smb_StripLastComponent(spacep->data, &lastComp, pathp);
#ifndef SPECIAL_FOLDERS
/* Make sure that lastComp is not NULL */
if (lastComp) {
}
/* now do namei and stat, and copy out the info */
- code = cm_NameI(cm_data.rootSCachep, (char *)(&p->parmsp[3]),
+ code = cm_NameI(cm_data.rootSCachep, pathp,
CM_FLAG_FOLLOW | CM_FLAG_CASEFOLD, userp, tidPathp, &req, &scp);
if (code) {
op = outp->datap;
/* for info level 108, figure out short name */
if (infoLevel == 0x108) {
- code = cm_GetShortName((char *)(&p->parmsp[3]), userp, &req,
+ code = cm_GetShortName(pathp, userp, &req,
tidPathp, scp->fid.vnode, shortName,
(size_t *) &len);
if (code) {
else if (infoLevel == SMB_QUERY_FILE_STANDARD_INFO) {
*((LARGE_INTEGER *)op) = scp->length; op += 8; /* alloc size */
*((LARGE_INTEGER *)op) = scp->length; op += 8; /* EOF */
- *((u_long *)op) = scp->linkCount; op += 4;
- *op++ = 0;
+ *((u_long *)op) = scp->linkCount; op += 4; /* Link count */
+ *op++ = 0; /* Delete Pending */
+ *op++ = ((scp->fileType == CM_SCACHETYPE_DIRECTORY ||
+ scp->fileType == CM_SCACHETYPE_MOUNTPOINT ||
+ scp->fileType == CM_SCACHETYPE_INVALID) ? 1 : 0);
*op++ = 0;
- *op++ = (scp->fileType == CM_SCACHETYPE_DIRECTORY ? 1 : 0);
*op++ = 0;
}
else if (infoLevel == SMB_QUERY_FILE_EA_INFO) {
unsigned short infoLevel;
int nbytesRequired;
unsigned short fid;
+ int delonclose = 0;
cm_user_t *userp;
smb_fid_t *fidp;
cm_scache_t *scp;
goto done;
}
+ lock_ObtainMutex(&fidp->mx);
+ delonclose = fidp->flags & SMB_FID_DELONCLOSE;
scp = fidp->scp;
+ cm_HoldSCache(scp);
+ lock_ReleaseMutex(&fidp->mx);
lock_ObtainMutex(&scp->mx);
code = cm_SyncOp(scp, NULL, userp, &req, 0,
CM_SCACHESYNC_NEEDCALLBACK | CM_SCACHESYNC_GETSTATUS);
else if (infoLevel == SMB_QUERY_FILE_STANDARD_INFO) {
*((LARGE_INTEGER *)op) = scp->length; op += 8; /* alloc size */
*((LARGE_INTEGER *)op) = scp->length; op += 8; /* EOF */
- *((u_long *)op) = scp->linkCount; op += 4;
- *op++ = ((fidp->flags & SMB_FID_DELONCLOSE) ? 1 : 0);
- *op++ = (scp->fileType == CM_SCACHETYPE_DIRECTORY ? 1 : 0);
+ *((u_long *)op) = scp->linkCount; op += 4; /* Link count */
+ *op++ = (delonclose ? 1 : 0); /* Delete Pending */
+ *op++ = ((scp->fileType == CM_SCACHETYPE_DIRECTORY ||
+ scp->fileType == CM_SCACHETYPE_MOUNTPOINT ||
+ scp->fileType == CM_SCACHETYPE_INVALID)? 1 : 0);
*op++ = 0;
*op++ = 0;
}
unsigned long len;
char *name;
+ lock_ReleaseMutex(&scp->mx);
+ lock_ObtainMutex(&fidp->mx);
+ lock_ObtainMutex(&scp->mx);
if (fidp->NTopen_wholepathp)
name = fidp->NTopen_wholepathp;
else
name = "\\"; /* probably can't happen */
- len = strlen(name);
+ lock_ReleaseMutex(&fidp->mx);
+ 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);
/* send and free the packets */
done:
lock_ReleaseMutex(&scp->mx);
+ cm_ReleaseSCache(scp);
cm_ReleaseUser(userp);
smb_ReleaseFID(fidp);
if (code == 0)
}
infoLevel = p->parmsp[1];
- osi_Log2(smb_logp,"ReceiveTran2SetFileInfo type=[%x] fid=[%x]", infoLevel, fid);
+ osi_Log2(smb_logp,"ReceiveTran2SetFileInfo type 0x%x fid %d", infoLevel, fid);
if (infoLevel > 0x104 || infoLevel < 0x101) {
osi_Log2(smb_logp, "Bad Tran2 op 0x%x infolevel 0x%x",
p->opcode, infoLevel);
return 0;
}
+ lock_ObtainMutex(&fidp->mx);
if (infoLevel == SMB_QUERY_FILE_STANDARD_INFO && !(fidp->flags & SMB_FID_OPENDELETE)) {
- smb_SendTran2Error(vcp, p, op, CM_ERROR_NOACCESS);
+ lock_ReleaseMutex(&fidp->mx);
smb_ReleaseFID(fidp);
+ smb_SendTran2Error(vcp, p, op, CM_ERROR_NOACCESS);
return 0;
}
if ((infoLevel == SMB_QUERY_FILE_EA_INFO || infoLevel == SMB_QUERY_FILE_NAME_INFO)
&& !(fidp->flags & SMB_FID_OPENWRITE)) {
- smb_SendTran2Error(vcp, p, op, CM_ERROR_NOACCESS);
+ lock_ReleaseMutex(&fidp->mx);
smb_ReleaseFID(fidp);
+ smb_SendTran2Error(vcp, p, op, CM_ERROR_NOACCESS);
return 0;
}
+ scp = fidp->scp;
+ cm_HoldSCache(scp);
+ lock_ReleaseMutex(&fidp->mx);
+
osi_Log1(smb_logp, "T2 SFileInfo type 0x%x", infoLevel);
outp = smb_GetTran2ResponsePacket(vcp, p, op, 2, 0);
goto done;
}
- scp = fidp->scp;
-
if (infoLevel == SMB_QUERY_FILE_BASIC_INFO) {
FILETIME lastMod;
unsigned int attribute;
code = cm_SyncOp(scp, NULL, userp, &req, 0,
CM_SCACHESYNC_GETSTATUS
| CM_SCACHESYNC_NEEDCALLBACK);
+ lock_ReleaseMutex(&scp->mx);
if (code) {
- lock_ReleaseMutex(&scp->mx);
goto done;
}
+ lock_ObtainMutex(&fidp->mx);
+ lock_ObtainMutex(&scp->mx);
+
/* prepare for setattr call */
attr.mask = 0;
}
}
lock_ReleaseMutex(&scp->mx);
+ lock_ReleaseMutex(&fidp->mx);
/* call setattr */
if (attr.mask)
if (*((char *)(p->datap))) {
code = cm_CheckNTDelete(fidp->NTopen_dscp, scp, userp,
&req);
- if (code == 0)
+ if (code == 0) {
+ lock_ObtainMutex(&fidp->mx);
fidp->flags |= SMB_FID_DELONCLOSE;
- }
+ lock_ReleaseMutex(&fidp->mx);
+ }
+ }
else {
code = 0;
+ lock_ObtainMutex(&fidp->mx);
fidp->flags &= ~SMB_FID_DELONCLOSE;
+ lock_ReleaseMutex(&fidp->mx);
}
}
done:
+ cm_ReleaseSCache(scp);
cm_ReleaseUser(userp);
smb_ReleaseFID(fidp);
if (code == 0)
requestFileName[0] == '\\' &&
!_strnicmp(cm_NetbiosName,&requestFileName[1],nbnLen) &&
requestFileName[nbnLen+1] == '\\' &&
- !_strnicmp("all",&requestFileName[nbnLen+2],3))
+ (!_strnicmp("all",&requestFileName[nbnLen+2],3) ||
+ !_strnicmp("*.",&requestFileName[nbnLen+2],2)))
{
USHORT * sp;
struct smb_v2_referral * v2ref;
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);
}
}
int parmSlot; /* which parm we're dealing with */
char *tidPathp;
cm_req_t req;
+ int created = 0;
cm_InitReq(&req);
free(hexp);
}
#endif
- userp = smb_GetUser(vcp, inp);
+ userp = smb_GetUserFromVCP(vcp, inp);
dscp = NULL;
code = smb_LookupTIDPath(vcp, ((smb_t *)inp)->tid, &tidPathp);
return CM_ERROR_BADSHARENAME;
}
#endif /* DFS_SUPPORT */
-
/* otherwise, scp points to the parent directory. Do a lookup,
* and truncate the file if we find it, otherwise we create the
* file.
smb_UnixTimeFromDosUTime(&setAttr.clientModTime, dosTime);
code = cm_Create(dscp, lastNamep, 0, &setAttr, &scp, userp,
&req);
- if (code == 0 && (dscp->flags & CM_SCACHEFLAG_ANYWATCH))
- smb_NotifyChange(FILE_ACTION_ADDED,
- FILE_NOTIFY_CHANGE_FILE_NAME,
- dscp, lastNamep, NULL, TRUE);
- if (!excl && code == CM_ERROR_EXISTS) {
+ if (code == 0) {
+ created = 1;
+ if (dscp->flags & CM_SCACHEFLAG_ANYWATCH)
+ smb_NotifyChange(FILE_ACTION_ADDED,
+ FILE_NOTIFY_CHANGE_FILE_NAME,
+ dscp, lastNamep, NULL, TRUE);
+ } else if (!excl && code == CM_ERROR_EXISTS) {
/* not an exclusive create, and someone else tried
* creating it already, then we open it anyway. We
* don't bother retrying after this, since if this next
fidp = smb_FindFID(vcp, 0, SMB_FLAG_CREATE);
osi_assert(fidp);
+ cm_HoldUser(userp);
+ lock_ObtainMutex(&fidp->mx);
/* save a pointer to the vnode */
fidp->scp = scp;
+ /* also the user */
+ fidp->userp = userp;
/* compute open mode */
if (openMode != 1)
if (openMode == 1 || openMode == 2)
fidp->flags |= SMB_FID_OPENWRITE;
+ /* remember if the file was newly created */
+ if (created)
+ fidp->flags |= SMB_FID_CREATED;
+
+ lock_ReleaseMutex(&fidp->mx);
smb_ReleaseFID(fidp);
cm_Open(scp, 0, userp);
fid = smb_ChainFID(fid, inp);
fidp = smb_FindFID(vcp, fid, 0);
- if (!fidp || (fidp->flags & SMB_FID_IOCTL)) {
+ if (!fidp)
+ return CM_ERROR_BADFD;
+
+ lock_ObtainMutex(&fidp->mx);
+ if (fidp->flags & SMB_FID_IOCTL) {
osi_Log0(smb_logp, "smb_ReceiveV3Locking BadFD");
+ lock_ReleaseMutex(&fidp->mx);
+ smb_ReleaseFID(fidp);
return CM_ERROR_BADFD;
}
+ scp = fidp->scp;
+ cm_HoldSCache(scp);
+ lock_ReleaseMutex(&fidp->mx);
+
/* set inp->fid so that later read calls in same msg can find fid */
inp->fid = fid;
- userp = smb_GetUser(vcp, inp);
+ userp = smb_GetUserFromVCP(vcp, inp);
- scp = fidp->scp;
lock_ObtainMutex(&scp->mx);
code = cm_SyncOp(scp, NULL, userp, &req, 0,
osi_QAdd((osi_queue_t **) &wlRequest->locks,
&wLock->q);
- osi_Log1(smb_logp, "smb_ReceiveV3Locking WaitingLock created 0x%x",
- (long) wLock);
+ osi_Log1(smb_logp, "smb_ReceiveV3Locking WaitingLock created 0x%p",
+ wLock);
code = 0;
continue;
lock_ObtainWrite(&smb_globalLock);
osi_QAdd((osi_queue_t **)&smb_allWaitingLocks,
&wlRequest->q);
- osi_Wakeup((long) &smb_allWaitingLocks);
+ osi_Wakeup((LONG_PTR)&smb_allWaitingLocks);
lock_ReleaseWrite(&smb_globalLock);
/* don't send reply immediately */
doneSync:
lock_ReleaseMutex(&scp->mx);
+ cm_ReleaseSCache(scp);
cm_ReleaseUser(userp);
smb_ReleaseFID(fidp);
fid = smb_ChainFID(fid, inp);
fidp = smb_FindFID(vcp, fid, 0);
- if (!fidp || (fidp->flags & SMB_FID_IOCTL)) {
+ if (!fidp)
+ return CM_ERROR_BADFD;
+
+ lock_ObtainMutex(&fidp->mx);
+ if (fidp->flags & SMB_FID_IOCTL) {
+ lock_ReleaseMutex(&fidp->mx);
+ smb_ReleaseFID(fidp);
return CM_ERROR_BADFD;
}
+ scp = fidp->scp;
+ cm_HoldSCache(scp);
+ lock_ReleaseMutex(&fidp->mx);
- userp = smb_GetUser(vcp, inp);
+ userp = smb_GetUserFromVCP(vcp, inp);
- scp = fidp->scp;
/* otherwise, stat the file */
lock_ObtainMutex(&scp->mx);
code = cm_SyncOp(scp, NULL, userp, &req, 0,
CM_SCACHESYNC_NEEDCALLBACK | CM_SCACHESYNC_GETSTATUS);
- if (code) goto done;
+ if (code)
+ goto done;
/* decode times. We need a search time, but the response to this
* call provides the date first, not the time, as returned in the
done:
lock_ReleaseMutex(&scp->mx);
+ cm_ReleaseSCache(scp);
cm_ReleaseUser(userp);
smb_ReleaseFID(fidp);
return code;
fid = smb_ChainFID(fid, inp);
fidp = smb_FindFID(vcp, fid, 0);
- if (!fidp || (fidp->flags & SMB_FID_IOCTL)) {
+ if (!fidp)
+ return CM_ERROR_BADFD;
+
+ lock_ObtainMutex(&fidp->mx);
+ if (fidp->flags & SMB_FID_IOCTL) {
+ lock_ReleaseMutex(&fidp->mx);
+ smb_ReleaseFID(fidp);
return CM_ERROR_BADFD;
}
+ scp = fidp->scp;
+ cm_HoldSCache(scp);
+ lock_ReleaseMutex(&fidp->mx);
- userp = smb_GetUser(vcp, inp);
+ userp = smb_GetUserFromVCP(vcp, inp);
- scp = fidp->scp;
/* now prepare to call cm_setattr. This message only sets various times,
* and AFS only implements mtime, and we'll set the mtime if that's
osi_Log1(smb_logp, "**smb_UnixTimeFromSearchTime failed searchTime=%ld", searchTime);
}
}
- else code = 0;
+ else
+ code = 0;
+ cm_ReleaseSCache(scp);
cm_ReleaseUser(userp);
smb_ReleaseFID(fidp);
return code;
}
+long smb_ReceiveV3WriteX(smb_vc_t *vcp, smb_packet_t *inp, smb_packet_t *outp)
+{
+ osi_hyper_t offset;
+ long count, written = 0, total_written = 0;
+ unsigned short fd;
+ unsigned pid;
+ smb_fid_t *fidp;
+ long code = 0;
+ cm_user_t *userp;
+ cm_attr_t truncAttr; /* attribute struct used for truncating file */
+ char *op;
+ int inDataBlockCount;
+
+ fd = smb_GetSMBParm(inp, 2);
+ count = smb_GetSMBParm(inp, 10);
+
+ offset.HighPart = 0;
+ offset.LowPart = smb_GetSMBParm(inp, 3) | (smb_GetSMBParm(inp, 4) << 16);
+
+ if (*inp->wctp == 14) {
+ /* we have a request with 64-bit file offsets */
+#ifdef AFS_LARGEFILES
+ offset.HighPart = smb_GetSMBParm(inp, 12) | (smb_GetSMBParm(inp, 13) << 16);
+#else
+ if ((smb_GetSMBParm(inp, 12) | (smb_GetSMBParm(inp, 13) << 16)) != 0) {
+ /* uh oh */
+ osi_Log0(smb_logp, "smb_ReceiveV3WriteX offset requires largefile support");
+ /* we shouldn't have received this op if we didn't specify
+ largefile support */
+ return CM_ERROR_BADOP;
+ }
+#endif
+ }
+
+ op = inp->data + smb_GetSMBParm(inp, 11);
+ inDataBlockCount = count;
+
+ osi_Log4(smb_logp, "smb_ReceiveV3WriteX fid %d, off 0x%x:%08x, size 0x%x",
+ fd, offset.HighPart, offset.LowPart, count);
+
+ fd = smb_ChainFID(fd, inp);
+ fidp = smb_FindFID(vcp, fd, 0);
+ if (!fidp)
+ return CM_ERROR_BADFD;
+
+ lock_ObtainMutex(&fidp->mx);
+ if (fidp->flags & SMB_FID_IOCTL) {
+ lock_ReleaseMutex(&fidp->mx);
+ code = smb_IoctlV3Write(fidp, vcp, inp, outp);
+ smb_ReleaseFID(fidp);
+ return code;
+ }
+ lock_ReleaseMutex(&fidp->mx);
+ userp = smb_GetUserFromVCP(vcp, inp);
+
+ /* special case: 0 bytes transferred means there is no data
+ transferred. A slight departure from SMB_COM_WRITE where this
+ means that we are supposed to truncate the file at this
+ position. */
+
+ {
+ cm_key_t key;
+ LARGE_INTEGER LOffset;
+ LARGE_INTEGER LLength;
+
+ pid = ((smb_t *) inp)->pid;
+ key = cm_GenerateKey(vcp->vcID, pid, fd);
+
+ LOffset.HighPart = offset.HighPart;
+ LOffset.LowPart = offset.LowPart;
+ LLength.HighPart = 0;
+ LLength.LowPart = count;
+
+ lock_ObtainMutex(&fidp->scp->mx);
+ code = cm_LockCheckWrite(fidp->scp, LOffset, LLength, key);
+ lock_ReleaseMutex(&fidp->scp->mx);
+
+ if (code)
+ goto done;
+ }
+
+ /*
+ * Work around bug in NT client
+ *
+ * When copying a file, the NT client should first copy the data,
+ * then copy the last write time. But sometimes the NT client does
+ * these in the wrong order, so the data copies would inadvertently
+ * cause the last write time to be overwritten. We try to detect this,
+ * and don't set client mod time if we think that would go against the
+ * intention.
+ */
+ lock_ObtainMutex(&fidp->mx);
+ if ((fidp->flags & SMB_FID_MTIMESETDONE) != SMB_FID_MTIMESETDONE) {
+ fidp->scp->mask |= CM_SCACHEMASK_CLIENTMODTIME;
+ fidp->scp->clientModTime = time(NULL);
+ }
+ lock_ReleaseMutex(&fidp->mx);
+
+ code = 0;
+ while ( code == 0 && count > 0 ) {
+#ifndef DJGPP
+ code = smb_WriteData(fidp, &offset, count, op, userp, &written);
+#else /* DJGPP */
+ code = smb_WriteData(fidp, &offset, count, op, userp, &written, FALSE);
+#endif /* !DJGPP */
+ if (code == 0 && written == 0)
+ code = CM_ERROR_PARTIALWRITE;
+
+ offset = LargeIntegerAdd(offset,
+ ConvertLongToLargeInteger(written));
+ count -= written;
+ total_written += written;
+ written = 0;
+ }
+
+ done_writing:
+
+ /* slots 0 and 1 are reserved for request chaining and will be
+ filled in when we return. */
+ smb_SetSMBParm(outp, 2, total_written);
+ smb_SetSMBParm(outp, 3, 0); /* reserved */
+ smb_SetSMBParm(outp, 4, 0); /* reserved */
+ smb_SetSMBParm(outp, 5, 0); /* reserved */
+ smb_SetSMBDataLength(outp, 0);
+
+ done:
+ smb_ReleaseFID(fidp);
+ cm_ReleaseUser(userp);
+
+ return code;
+}
long smb_ReceiveV3ReadX(smb_vc_t *vcp, smb_packet_t *inp, smb_packet_t *outp)
{
fd = smb_GetSMBParm(inp, 2);
count = smb_GetSMBParm(inp, 5);
- offset.HighPart = 0; /* too bad */
offset.LowPart = smb_GetSMBParm(inp, 3) | (smb_GetSMBParm(inp, 4) << 16);
- osi_Log3(smb_logp, "smb_ReceiveV3Read fd %d, off 0x%x, size 0x%x",
- fd, offset.LowPart, count);
-
+ if (*inp->wctp == 12) {
+ /* a request with 64-bit offsets */
+#ifdef AFS_LARGEFILES
+ offset.HighPart = smb_GetSMBParm(inp, 10) | (smb_GetSMBParm(inp, 11) << 16);
+
+ if (LargeIntegerLessThanZero(offset)) {
+ osi_Log2(smb_logp, "smb_ReceiveV3Read offset too large (0x%x:%08x)",
+ offset.HighPart, offset.LowPart);
+ return CM_ERROR_BADSMB;
+ }
+#else
+ if ((smb_GetSMBParm(inp, 10) | (smb_GetSMBParm(inp, 11) << 16)) != 0) {
+ osi_Log0(smb_logp, "smb_ReceiveV3Read offset is 64-bit. Dropping");
+ return CM_ERROR_BADSMB;
+ } else {
+ offset.HighPart = 0;
+ }
+#endif
+ } else {
+ offset.HighPart = 0;
+ }
+
+ osi_Log4(smb_logp, "smb_ReceiveV3Read fd %d, off 0x%x:%08x, size 0x%x",
+ fd, offset.HighPart, offset.LowPart, count);
+
fd = smb_ChainFID(fd, inp);
fidp = smb_FindFID(vcp, fd, 0);
if (!fidp) {
/* set inp->fid so that later read calls in same msg can find fid */
inp->fid = fd;
+ lock_ObtainMutex(&fidp->mx);
if (fidp->flags & SMB_FID_IOCTL) {
- return smb_IoctlV3Read(fidp, vcp, inp, outp);
+ lock_ReleaseMutex(&fidp->mx);
+ code = smb_IoctlV3Read(fidp, vcp, inp, outp);
+ smb_ReleaseFID(fidp);
+ return code;
}
+ lock_ReleaseMutex(&fidp->mx);
- userp = smb_GetUser(vcp, inp);
+ userp = smb_GetUserFromVCP(vcp, inp);
/* 0 and 1 are reserved for request chaining, were setup by our caller,
* and will be further filled in after we return.
char *tidPathp;
BOOL foundscp;
cm_req_t req;
+ int created = 0;
cm_InitReq(&req);
}
#endif
- userp = smb_GetUser(vcp, inp);
+ userp = smb_GetUserFromVCP(vcp, inp);
if (!userp) {
osi_Log1(smb_logp, "NTCreateX Invalid user [%d]", ((smb_t *) inp)->uid);
free(realPathp);
}
if (baseFid == 0) {
+ baseFidp = NULL;
baseDirp = cm_data.rootSCachep;
code = smb_LookupTIDPath(vcp, ((smb_t *)inp)->tid, &tidPathp);
if (code == CM_ERROR_TIDIPC) {
if (shareAccess & FILE_SHARE_WRITE)
fidflags |= SMB_FID_SHARE_WRITE;
+ osi_Log1(smb_logp, "NTCreateX fidflags 0x%x", fidflags);
code = 0;
/* For an exclusive create, we want to do a case sensitive match for the last component. */
cm_ReleaseSCache(dscp);
cm_ReleaseUser(userp);
free(realPathp);
+ if (baseFidp)
+ smb_ReleaseFID(baseFidp);
if ( WANTS_DFS_PATHNAMES(inp) )
return CM_ERROR_PATH_NOT_COVERED;
else
cm_ReleaseSCache(dscp);
cm_ReleaseUser(userp);
free(realPathp);
+ if (baseFidp)
+ smb_ReleaseFID(baseFidp);
return CM_ERROR_EXISTS;
}
}
cm_ReleaseSCache(scp);
cm_ReleaseUser(userp);
free(realPathp);
+ if (baseFidp)
+ smb_ReleaseFID(baseFidp);
if ( WANTS_DFS_PATHNAMES(inp) )
return CM_ERROR_PATH_NOT_COVERED;
else
cm_ReleaseSCache(dscp);
cm_ReleaseUser(userp);
free(realPathp);
+ if (baseFidp)
+ smb_ReleaseFID(baseFidp);
if ( WANTS_DFS_PATHNAMES(inp) )
return CM_ERROR_PATH_NOT_COVERED;
else
treeStartp = realPathp + (tp - spacep->data);
if (*tp && !smb_IsLegalFilename(tp)) {
- if (baseFid != 0)
+ if (baseFidp)
smb_ReleaseFID(baseFidp);
cm_ReleaseUser(userp);
free(realPathp);
/* we might have scp and we might have dscp */
- if (baseFid != 0)
+ if (baseFidp)
smb_ReleaseFID(baseFidp);
if (code) {
/* we have scp and dscp */
} else {
/* we have scp but not dscp */
- if (baseFid != 0)
+ if (baseFidp)
smb_ReleaseFID(baseFidp);
}
* 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);
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)
setAttr.mask = CM_ATTRMASK_CLIENTMODTIME;
setAttr.clientModTime = time(NULL);
code = cm_Create(dscp, lastNamep, 0, &setAttr, &scp, userp, &req);
- if (code == 0 && (dscp->flags & CM_SCACHEFLAG_ANYWATCH))
- smb_NotifyChange(FILE_ACTION_ADDED,
- FILE_NOTIFY_CHANGE_FILE_NAME,
- dscp, lastNamep, NULL, TRUE);
- if (code == CM_ERROR_EXISTS && createDisp != FILE_CREATE) {
+ if (code == 0) {
+ created = 1;
+ if (dscp->flags & CM_SCACHEFLAG_ANYWATCH)
+ smb_NotifyChange(FILE_ACTION_ADDED,
+ FILE_NOTIFY_CHANGE_FILE_NAME,
+ dscp, lastNamep, NULL, TRUE);
+ } else if (code == CM_ERROR_EXISTS && createDisp != FILE_CREATE) {
/* Not an exclusive create, and someone else tried
* creating it already, then we open it anyway. We
* don't bother retrying after this, since if this next
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++;
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 &&
lock_ReleaseMutex(&scp->mx);
if (code) {
- fidp->flags = SMB_FID_DELETE;
+ /* shouldn't this be smb_CloseFID() fidp->flags = SMB_FID_DELETE; */
+ smb_CloseFID(vcp, fidp, NULL, 0);
smb_ReleaseFID(fidp);
cm_ReleaseSCache(scp);
cm_ReleaseUser(userp);
free(realPathp);
- return CM_ERROR_SHARING_VIOLATION;
+ return code;
}
}
+ lock_ObtainMutex(&fidp->mx);
/* save a pointer to the vnode */
fidp->scp = scp; /* Hold transfered to fidp->scp and no longer needed */
fidp->flags = fidflags;
+ /* remember if the file was newly created */
+ if (created)
+ fidp->flags |= SMB_FID_CREATED;
+
/* save parent dir and pathname for delete or change notification */
if (fidflags & (SMB_FID_OPENDELETE | SMB_FID_OPENWRITE)) {
fidp->flags |= SMB_FID_NTOPEN;
fidp->NTopen_pathp = strdup(lastNamep);
}
fidp->NTopen_wholepathp = realPathp;
+ lock_ReleaseMutex(&fidp->mx);
/* we don't need this any longer */
if (dscp) {
smb_SetSMBParm(outp, parmSlot, 0); parmSlot++; /* filetype */
smb_SetSMBParm(outp, parmSlot, 0); parmSlot++; /* dev state */
smb_SetSMBParmByte(outp, parmSlot,
- scp->fileType == CM_SCACHETYPE_DIRECTORY); /* is a dir? */
+ (scp->fileType == CM_SCACHETYPE_DIRECTORY ||
+ scp->fileType == CM_SCACHETYPE_MOUNTPOINT ||
+ scp->fileType == CM_SCACHETYPE_INVALID) ? 1 : 0); /* is a dir? */
lock_ReleaseMutex(&scp->mx);
smb_SetSMBDataLength(outp, 0);
ULONG *lparmp;
char *outData;
cm_req_t req;
+ int created = 0;
cm_InitReq(&req);
}
#endif
- userp = smb_GetUser(vcp, inp);
+ userp = smb_GetUserFromVCP(vcp, inp);
if (!userp) {
osi_Log1(smb_logp, "NTTranCreate invalid user [%d]", ((smb_t *) inp)->uid);
free(realPathp);
}
if (baseFid == 0) {
+ baseFidp = NULL;
baseDirp = cm_data.rootSCachep;
code = smb_LookupTIDPath(vcp, ((smb_t *)inp)->tid, &tidPathp);
if (code == CM_ERROR_TIDIPC) {
} else {
baseFidp = smb_FindFID(vcp, baseFid, 0);
if (!baseFidp) {
- osi_Log1(smb_logp, "NTTranCreate Invalid fid [%d]", baseFid);
+ osi_Log1(smb_logp, "NTTranCreate Invalid fid [%d]", baseFid);
free(realPathp);
cm_ReleaseUser(userp);
return CM_ERROR_INVAL;
cm_ReleaseSCache(dscp);
cm_ReleaseUser(userp);
free(realPathp);
+ if (baseFidp)
+ smb_ReleaseFID(baseFidp);
if ( WANTS_DFS_PATHNAMES(inp) )
return CM_ERROR_PATH_NOT_COVERED;
else
cm_ReleaseSCache(dscp);
cm_ReleaseUser(userp);
free(realPathp);
+ if (baseFidp)
+ smb_ReleaseFID(baseFidp);
return CM_ERROR_EXISTS;
}
}
cm_ReleaseSCache(scp);
cm_ReleaseUser(userp);
free(realPathp);
+ if (baseFidp)
+ smb_ReleaseFID(baseFidp);
if ( WANTS_DFS_PATHNAMES(inp) )
return CM_ERROR_PATH_NOT_COVERED;
else
cm_ReleaseSCache(dscp);
cm_ReleaseUser(userp);
free(realPathp);
+ if (baseFidp)
+ smb_ReleaseFID(baseFidp);
if ( WANTS_DFS_PATHNAMES(inp) )
return CM_ERROR_PATH_NOT_COVERED;
else
cm_FreeSpace(spacep);
- if (baseFid != 0) {
+ if (baseFidp)
smb_ReleaseFID(baseFidp);
- baseFidp = 0;
- }
if (code) {
cm_ReleaseUser(userp);
return code;
}
- if (!lastNamep) lastNamep = realPathp;
- else lastNamep++;
+ if (!lastNamep)
+ lastNamep = realPathp;
+ else
+ lastNamep++;
if (!smb_IsLegalFilename(lastNamep))
return CM_ERROR_BADNTFILENAME;
}
}
} else {
- if (baseFid != 0) {
+ if (baseFidp)
smb_ReleaseFID(baseFidp);
- baseFidp = 0;
- }
cm_FreeSpace(spacep);
}
setAttr.clientModTime = time(NULL);
code = cm_Create(dscp, lastNamep, 0, &setAttr, &scp, userp,
&req);
- if (code == 0 && (dscp->flags & CM_SCACHEFLAG_ANYWATCH))
- smb_NotifyChange(FILE_ACTION_ADDED,
- FILE_NOTIFY_CHANGE_FILE_NAME,
- dscp, lastNamep, NULL, TRUE);
- if (code == CM_ERROR_EXISTS && createDisp != FILE_CREATE) {
+ if (code == 0) {
+ created = 1;
+ if (dscp->flags & CM_SCACHEFLAG_ANYWATCH)
+ smb_NotifyChange(FILE_ACTION_ADDED,
+ FILE_NOTIFY_CHANGE_FILE_NAME,
+ dscp, lastNamep, NULL, TRUE);
+ } else if (code == CM_ERROR_EXISTS && createDisp != FILE_CREATE) {
/* Not an exclusive create, and someone else tried
* creating it already, then we open it anyway. We
* don't bother retrying after this, since if this next
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 &&
lock_ReleaseMutex(&scp->mx);
if (code) {
- fidp->flags = SMB_FID_DELETE;
+ /* Shouldn't this be smb_CloseFID()? fidp->flags = SMB_FID_DELETE; */
+ smb_CloseFID(vcp, fidp, NULL, 0);
smb_ReleaseFID(fidp);
cm_ReleaseSCache(scp);
}
}
+ lock_ObtainMutex(&fidp->mx);
/* save a pointer to the vnode */
fidp->scp = scp;
fidp->flags = fidflags;
+ /* remember if the file was newly created */
+ if (created)
+ fidp->flags |= SMB_FID_CREATED;
+
/* save parent dir and pathname for deletion or change notification */
if (fidflags & (SMB_FID_OPENDELETE | SMB_FID_OPENWRITE)) {
fidp->flags |= SMB_FID_NTOPEN;
fidp->NTopen_pathp = strdup(lastNamep);
}
fidp->NTopen_wholepathp = realPathp;
+ lock_ReleaseMutex(&fidp->mx);
/* we don't need this any longer */
if (dscp)
*((LARGE_INTEGER *)outData) = scp->length; outData += 8; /* EOF */
*((USHORT *)outData) = 0; outData += 2; /* filetype */
*((USHORT *)outData) = 0; outData += 2; /* dev state */
- *((USHORT *)outData) = (scp->fileType == CM_SCACHETYPE_DIRECTORY);
+ *((USHORT *)outData) = ((scp->fileType == CM_SCACHETYPE_DIRECTORY ||
+ scp->fileType == CM_SCACHETYPE_MOUNTPOINT ||
+ scp->fileType == CM_SCACHETYPE_INVALID) ? 1 : 0);
outData += 2; /* is a dir? */
lock_ReleaseMutex(&scp->mx);
} else {
*((LARGE_INTEGER *)outData) = scp->length; outData += 8; /* EOF */
*((USHORT *)outData) = 0; outData += 2; /* filetype */
*((USHORT *)outData) = 0; outData += 2; /* dev state */
- *((USHORT *)outData) = (scp->fileType == CM_SCACHETYPE_DIRECTORY);
+ *((USHORT *)outData) = ((scp->fileType == CM_SCACHETYPE_DIRECTORY ||
+ scp->fileType == CM_SCACHETYPE_MOUNTPOINT ||
+ scp->fileType == CM_SCACHETYPE_INVALID) ? 1 : 0);
outData += 1; /* is a dir? */
memset(outData,0,24); outData += 24; /* Volume ID and file ID */
*((ULONG *)outData) = 0x001f01ffL; outData += 4; /* Maxmimal access rights */
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, afs_uint32 flags)
{
- /*int newUid;*/
smb_username_t *unp;
+ cm_user_t * userp;
- unp = smb_FindUserByName(usern, machine, SMB_FLAG_CREATE);
+ unp = smb_FindUserByName(usern, machine, flags);
if (!unp->userp) {
lock_ObtainMutex(&unp->mx);
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;
}