From 8f0422422defc4e74f05e0e36c54f810c204bfa5 Mon Sep 17 00:00:00 2001 From: Jeffrey Altman Date: Thu, 18 Mar 2004 06:13:55 +0000 Subject: [PATCH] the-correct-mkdir-fix-20040318 Apply the correct file including the fix to the MIT recursive directory creation patch. --- src/WINNT/afsd/smb3.c | 2848 ++++++++++++++++++++++++------------------------- 1 file changed, 1422 insertions(+), 1426 deletions(-) diff --git a/src/WINNT/afsd/smb3.c b/src/WINNT/afsd/smb3.c index ec4b853..a41d5c7 100644 --- a/src/WINNT/afsd/smb3.c +++ b/src/WINNT/afsd/smb3.c @@ -25,8 +25,6 @@ #include "smb.h" -extern smb_vc_t *dead_vcp; - extern osi_hyper_t hzero; smb_packet_t *smb_Directory_Watches = NULL; @@ -111,7 +109,7 @@ long smb_ReceiveV3SessionSetupX(smb_vc_t *vcp, smb_packet_t *inp, smb_packet_t * { char *tp; char *usern, *pwd, *pwdx; - smb_user_t *uidp, *dead_uidp; + smb_user_t *uidp; unsigned short newUid; unsigned long caps; cm_user_t *userp; @@ -164,9 +162,10 @@ long smb_ReceiveV3SessionSetupX(smb_vc_t *vcp, smb_packet_t *inp, smb_packet_t * if (!userp) userp = cm_NewUser(); lock_ObtainMutex(&vcp->mx); - if(!vcp->uidCounter) vcp->uidCounter++; /* handle unlikely wraparounds */ - newUid = (strlen(usern)==0)?0:vcp->uidCounter++; - lock_ReleaseMutex(&vcp->mx); + if (!vcp->uidCounter) + vcp->uidCounter++; /* handle unlikely wraparounds */ + newUid = (strlen(usern)==0)?0:vcp->uidCounter++; + lock_ReleaseMutex(&vcp->mx); /* Create a new smb_user_t structure and connect them up */ lock_ObtainMutex(&unp->mx); @@ -176,7 +175,7 @@ long smb_ReceiveV3SessionSetupX(smb_vc_t *vcp, smb_packet_t *inp, smb_packet_t * 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]",vcp,vcp->lana,vcp->lsn,newUid,usern); + osi_LogEvent("AFS smb_ReceiveV3SessionSetupX",NULL,"MakeNewUser:VCP[%x],Lana[%d],lsn[%d],userid[%d],TicketKTCName[%s]",(int)vcp,vcp->lana,vcp->lsn,newUid,usern); osi_Log4(afsd_logp,"smb_ReceiveV3SessionSetupX MakeNewUser:VCP[%x],Lana[%d],lsn[%d],userid[%d]",vcp,vcp->lana,vcp->lsn,newUid); lock_ReleaseMutex(&uidp->mx); smb_ReleaseUID(uidp); @@ -204,9 +203,9 @@ long smb_ReceiveV3UserLogoffX(smb_vc_t *vcp, smb_packet_t *inp, smb_packet_t *ou 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) { + uidp = smb_FindUID(vcp, ((smb_t *)inp)->uid, 0); + /* TODO: smb_ReleaseUID() ? */ + if (uidp) { char *s1 = NULL, *s2 = NULL; if (s2 == NULL) s2 = " "; @@ -313,29 +312,29 @@ smb_tran2Packet_t *smb_NewTran2Packet(smb_vc_t *vcp, smb_packet_t *inp, int totalParms, int totalData) { smb_tran2Packet_t *tp; - smb_t *smbp; + smb_t *smbp; - smbp = (smb_t *) inp->data; + smbp = (smb_t *) inp->data; tp = malloc(sizeof(*tp)); - memset(tp, 0, sizeof(*tp)); - tp->vcp = vcp; - smb_HoldVC(vcp); - tp->curData = tp->curParms = 0; - tp->totalData = totalData; - tp->totalParms = totalParms; - tp->tid = smbp->tid; - tp->mid = smbp->mid; - tp->uid = smbp->uid; - tp->pid = smbp->pid; + memset(tp, 0, sizeof(*tp)); + tp->vcp = vcp; + smb_HoldVC(vcp); + tp->curData = tp->curParms = 0; + tp->totalData = totalData; + tp->totalParms = totalParms; + tp->tid = smbp->tid; + tp->mid = smbp->mid; + tp->uid = smbp->uid; + tp->pid = smbp->pid; tp->res[0] = smbp->res[0]; osi_QAdd((osi_queue_t **)&smb_tran2AssemblyQueuep, &tp->q); - tp->opcode = smb_GetSMBParm(inp, 14); + tp->opcode = smb_GetSMBParm(inp, 14); if (totalParms != 0) - tp->parmsp = malloc(totalParms); + tp->parmsp = malloc(totalParms); if (totalData != 0) - tp->datap = malloc(totalData); + tp->datap = malloc(totalData); tp->flags |= SMB_TRAN2PFLAG_ALLOC; - return tp; + return tp; } smb_tran2Packet_t *smb_GetTran2ResponsePacket(smb_vc_t *vcp, @@ -382,14 +381,14 @@ smb_tran2Packet_t *smb_GetTran2ResponsePacket(smb_vc_t *vcp, /* free a tran2 packet; must be called with smb_globalLock held */ void smb_FreeTran2Packet(smb_tran2Packet_t *t2p) { - if (t2p->vcp) smb_ReleaseVC(t2p->vcp); + if (t2p->vcp) smb_ReleaseVC(t2p->vcp); if (t2p->flags & SMB_TRAN2PFLAG_ALLOC) { if (t2p->parmsp) free(t2p->parmsp); if (t2p->datap) free(t2p->datap); } - free(t2p); + free(t2p); } /* called with a VC, an input packet to respond to, and an error code. @@ -496,17 +495,17 @@ void smb_SendTran2Packet(smb_vc_t *vcp, smb_tran2Packet_t *t2p, smb_packet_t *tp long smb_ReceiveV3Tran2A(smb_vc_t *vcp, smb_packet_t *inp, smb_packet_t *outp) { - smb_tran2Packet_t *asp; - int totalParms; - int totalData; - int parmDisp; - int dataDisp; - int parmOffset; - int dataOffset; - int parmCount; - int dataCount; - int firstPacket; - long code; + smb_tran2Packet_t *asp; + int totalParms; + int totalData; + int parmDisp; + int dataDisp; + int parmOffset; + int dataOffset; + int parmCount; + int dataCount; + int firstPacket; + long code; /* We sometimes see 0 word count. What to do? */ if (*inp->wctp == 0) { @@ -519,109 +518,108 @@ long smb_ReceiveV3Tran2A(smb_vc_t *vcp, smb_packet_t *inp, smb_packet_t *outp) 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); + 1, inp->ncb_length, ptbuf, inp); DeregisterEventSource(h); #else /* DJGPP */ osi_Log0(afsd_logp, "TRANSACTION2 word count = 0"); #endif /* !DJGPP */ - smb_SetSMBDataLength(outp, 0); - smb_SendPacket(vcp, outp); + smb_SetSMBDataLength(outp, 0); + smb_SendPacket(vcp, outp); return 0; } - totalParms = smb_GetSMBParm(inp, 0); - totalData = smb_GetSMBParm(inp, 1); - - firstPacket = (inp->inCom == 0x32); - + totalParms = smb_GetSMBParm(inp, 0); + totalData = smb_GetSMBParm(inp, 1); + + firstPacket = (inp->inCom == 0x32); + /* find the packet we're reassembling */ lock_ObtainWrite(&smb_globalLock); - asp = smb_FindTran2Packet(vcp, inp); - if (!asp) { - asp = smb_NewTran2Packet(vcp, inp, totalParms, totalData); + asp = smb_FindTran2Packet(vcp, inp); + if (!asp) { + asp = smb_NewTran2Packet(vcp, inp, totalParms, totalData); } - lock_ReleaseWrite(&smb_globalLock); - - /* now merge in this latest packet; start by looking up offsets */ + lock_ReleaseWrite(&smb_globalLock); + + /* now merge in this latest packet; start by looking up offsets */ if (firstPacket) { parmDisp = dataDisp = 0; - parmOffset = smb_GetSMBParm(inp, 10); - dataOffset = smb_GetSMBParm(inp, 12); - parmCount = smb_GetSMBParm(inp, 9); - dataCount = smb_GetSMBParm(inp, 11); + parmOffset = smb_GetSMBParm(inp, 10); + dataOffset = smb_GetSMBParm(inp, 12); + parmCount = smb_GetSMBParm(inp, 9); + dataCount = smb_GetSMBParm(inp, 11); asp->maxReturnParms = smb_GetSMBParm(inp, 2); - asp->maxReturnData = smb_GetSMBParm(inp, 3); + asp->maxReturnData = smb_GetSMBParm(inp, 3); osi_Log3(afsd_logp, "SMB3 received T2 init packet total data %d, cur data %d, max return data %d", - totalData, dataCount, asp->maxReturnData); - } - else { - parmDisp = smb_GetSMBParm(inp, 4); - parmOffset = smb_GetSMBParm(inp, 3); - dataDisp = smb_GetSMBParm(inp, 7); - dataOffset = smb_GetSMBParm(inp, 6); - parmCount = smb_GetSMBParm(inp, 2); - dataCount = smb_GetSMBParm(inp, 5); - - osi_Log2(afsd_logp, "SMB3 received T2 aux packet parms %d, data %d", - parmCount, dataCount); - } - - /* now copy the parms and data */ - if( parmCount != 0 ) - { - memcpy(((char *)asp->parmsp) + parmDisp, inp->data + parmOffset, parmCount); - } - if( dataCount != 0 ) - { - memcpy(asp->datap + dataDisp, inp->data + dataOffset, dataCount); + totalData, dataCount, asp->maxReturnData); + } + else { + parmDisp = smb_GetSMBParm(inp, 4); + parmOffset = smb_GetSMBParm(inp, 3); + dataDisp = smb_GetSMBParm(inp, 7); + dataOffset = smb_GetSMBParm(inp, 6); + parmCount = smb_GetSMBParm(inp, 2); + dataCount = smb_GetSMBParm(inp, 5); + + osi_Log2(afsd_logp, "SMB3 received T2 aux packet parms %d, data %d", + parmCount, dataCount); } - /* account for new bytes */ - asp->curData += dataCount; - asp->curParms += parmCount; + /* now copy the parms and data */ + if ( parmCount != 0 ) + { + memcpy(((char *)asp->parmsp) + parmDisp, inp->data + parmOffset, parmCount); + } + if ( dataCount != 0 ) { + memcpy(asp->datap + dataDisp, inp->data + dataOffset, dataCount); + } - /* finally, if we're done, remove the packet from the queue and dispatch it */ - if (asp->totalData <= asp->curData && asp->totalParms <= asp->curParms) { + /* account for new bytes */ + asp->curData += dataCount; + asp->curParms += parmCount; + + /* finally, if we're done, remove the packet from the queue and dispatch it */ + if (asp->totalData <= asp->curData && asp->totalParms <= asp->curParms) { /* we've received it all */ - lock_ObtainWrite(&smb_globalLock); + lock_ObtainWrite(&smb_globalLock); osi_QRemove((osi_queue_t **) &smb_tran2AssemblyQueuep, &asp->q); - lock_ReleaseWrite(&smb_globalLock); - - /* 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]",vcp,vcp->lana,vcp->lsn); - osi_Log4(afsd_logp,"AFS Server - Dispatch-2 %s vcp[%x] 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(afsd_logp,"AFS Server - Dispatch-2 [INVALID] op[%x] vcp[%x] lana[%d] lsn[%d]", asp->opcode, vcp, vcp->lana, vcp->lsn); - code = CM_ERROR_BADOP; - } + lock_ReleaseWrite(&smb_globalLock); + + /* 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(afsd_logp,"AFS Server - Dispatch-2 %s vcp[%x] 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(afsd_logp,"AFS Server - Dispatch-2 [INVALID] op[%x] vcp[%x] lana[%d] lsn[%d]", asp->opcode, vcp, vcp->lana, vcp->lsn); + code = CM_ERROR_BADOP; + } /* if an error is returned, we're supposed to send an error packet, - * otherwise the dispatched function already did the data sending. - * We give dispatched proc the responsibility since it knows how much - * space to allocate. - */ - if (code != 0) { - smb_SendTran2Error(vcp, asp, outp, code); - } + * otherwise the dispatched function already did the data sending. + * We give dispatched proc the responsibility since it knows how much + * space to allocate. + */ + if (code != 0) { + smb_SendTran2Error(vcp, asp, outp, code); + } /* free the input tran 2 packet */ lock_ObtainWrite(&smb_globalLock); - smb_FreeTran2Packet(asp); + smb_FreeTran2Packet(asp); lock_ReleaseWrite(&smb_globalLock); - } - else if (firstPacket) { + } + else if (firstPacket) { /* the first packet in a multi-packet request, we need to send an - * ack to get more data. - */ - smb_SetSMBDataLength(outp, 0); - smb_SendPacket(vcp, outp); - } + * ack to get more data. + */ + smb_SetSMBDataLength(outp, 0); + smb_SendPacket(vcp, outp); + } return 0; } @@ -629,98 +627,98 @@ long smb_ReceiveV3Tran2A(smb_vc_t *vcp, smb_packet_t *inp, smb_packet_t *outp) long smb_ReceiveTran2Open(smb_vc_t *vcp, smb_tran2Packet_t *p, smb_packet_t *op) { char *pathp; - smb_tran2Packet_t *outp; - long code; + smb_tran2Packet_t *outp; + long code; cm_space_t *spacep; - int excl; - cm_user_t *userp; - cm_scache_t *dscp; /* dir we're dealing with */ - cm_scache_t *scp; /* file we're creating */ - cm_attr_t setAttr; - int initialModeBits; - smb_fid_t *fidp; - int attributes; - char *lastNamep; - long dosTime; - int openFun; - int trunc; - int openMode; - int extraInfo; - int openAction; - int parmSlot; /* which parm we're dealing with */ - long returnEALength; + int excl; + cm_user_t *userp; + cm_scache_t *dscp; /* dir we're dealing with */ + cm_scache_t *scp; /* file we're creating */ + cm_attr_t setAttr; + int initialModeBits; + smb_fid_t *fidp; + int attributes; + char *lastNamep; + long dosTime; + int openFun; + int trunc; + int openMode; + int extraInfo; + int openAction; + int parmSlot; /* which parm we're dealing with */ + long returnEALength; char *tidPathp; cm_req_t req; cm_InitReq(&req); - scp = NULL; - + scp = NULL; + extraInfo = (p->parmsp[0] & 1); /* return extra info */ - returnEALength = (p->parmsp[0] & 8); /* return extended attr length */ + returnEALength = (p->parmsp[0] & 8); /* return extended attr length */ openFun = p->parmsp[6]; /* open function */ - excl = ((openFun & 3) == 0); - trunc = ((openFun & 3) == 2); /* truncate it */ + excl = ((openFun & 3) == 0); + trunc = ((openFun & 3) == 2); /* truncate it */ openMode = (p->parmsp[1] & 0x7); - openAction = 0; /* tracks what we did */ - - attributes = p->parmsp[3]; - dosTime = p->parmsp[4] | (p->parmsp[5] << 16); + openAction = 0; /* tracks what we did */ + attributes = p->parmsp[3]; + dosTime = p->parmsp[4] | (p->parmsp[5] << 16); + /* compute initial mode bits based on read-only flag in attributes */ - initialModeBits = 0666; - if (attributes & 1) initialModeBits &= ~0222; - - pathp = (char *) (&p->parmsp[14]); - - outp = smb_GetTran2ResponsePacket(vcp, p, op, 40, 0); + initialModeBits = 0666; + if (attributes & 1) initialModeBits &= ~0222; + + pathp = (char *) (&p->parmsp[14]); + + outp = smb_GetTran2ResponsePacket(vcp, p, op, 40, 0); spacep = cm_GetSpace(); - smb_StripLastComponent(spacep->data, &lastNamep, pathp); + smb_StripLastComponent(spacep->data, &lastNamep, pathp); if (lastNamep && strcmp(lastNamep, SMB_IOCTL_FILENAME) == 0) { /* special case magic file name for receiving IOCTL requests - * (since IOCTL calls themselves aren't getting through). - */ - fidp = smb_FindFID(vcp, 0, SMB_FLAG_CREATE); - smb_SetupIoctlFid(fidp, spacep); + * (since IOCTL calls themselves aren't getting through). + */ + fidp = smb_FindFID(vcp, 0, SMB_FLAG_CREATE); + smb_SetupIoctlFid(fidp, spacep); - /* copy out remainder of the parms */ + /* copy out remainder of the parms */ parmSlot = 0; outp->parmsp[parmSlot] = fidp->fid; parmSlot++; if (extraInfo) { - outp->parmsp[parmSlot] = /* attrs */ 0; parmSlot++; - outp->parmsp[parmSlot] = 0; parmSlot++; /* mod time */ - outp->parmsp[parmSlot] = 0; parmSlot++; - outp->parmsp[parmSlot] = 0; parmSlot++; /* len */ - outp->parmsp[parmSlot] = 0x7fff; parmSlot++; - outp->parmsp[parmSlot] = openMode; parmSlot++; - outp->parmsp[parmSlot] = 0; parmSlot++; /* file type 0 ==> normal file or dir */ - outp->parmsp[parmSlot] = 0; parmSlot++; /* IPC junk */ - } + outp->parmsp[parmSlot] = /* attrs */ 0; parmSlot++; + outp->parmsp[parmSlot] = 0; parmSlot++; /* mod time */ + outp->parmsp[parmSlot] = 0; parmSlot++; + outp->parmsp[parmSlot] = 0; parmSlot++; /* len */ + outp->parmsp[parmSlot] = 0x7fff; parmSlot++; + outp->parmsp[parmSlot] = openMode; parmSlot++; + outp->parmsp[parmSlot] = 0; parmSlot++; /* file type 0 ==> normal file or dir */ + outp->parmsp[parmSlot] = 0; parmSlot++; /* IPC junk */ + } /* and the final "always present" stuff */ - outp->parmsp[parmSlot] = /* openAction found existing file */ 1; parmSlot++; + outp->parmsp[parmSlot] = /* openAction found existing file */ 1; parmSlot++; /* next write out the "unique" ID */ outp->parmsp[parmSlot] = 0x1234; parmSlot++; outp->parmsp[parmSlot] = 0x5678; parmSlot++; - outp->parmsp[parmSlot] = 0; parmSlot++; + outp->parmsp[parmSlot] = 0; parmSlot++; if (returnEALength) { outp->parmsp[parmSlot] = 0; parmSlot++; outp->parmsp[parmSlot] = 0; parmSlot++; - } - - outp->totalData = 0; - outp->totalParms = parmSlot * 2; - - smb_SendTran2Packet(vcp, outp, op); - - smb_FreeTran2Packet(outp); + } + + outp->totalData = 0; + outp->totalParms = parmSlot * 2; + + smb_SendTran2Packet(vcp, outp, op); + + smb_FreeTran2Packet(outp); /* and clean up fid reference */ - smb_ReleaseFID(fidp); - return 0; - } + smb_ReleaseFID(fidp); + return 0; + } #ifdef DEBUG_VERBOSE { @@ -733,132 +731,132 @@ long smb_ReceiveTran2Open(smb_vc_t *vcp, smb_tran2Packet_t *p, smb_packet_t *op) #endif userp = smb_GetTran2User(vcp, p); - /* In the off chance that userp is NULL, we log and abandon */ - if(!userp) { - osi_Log1(afsd_logp, "ReceiveTran2Open user [%d] not resolvable", p->uid); - smb_FreeTran2Packet(outp); - return CM_ERROR_BADSMB; - } + /* In the off chance that userp is NULL, we log and abandon */ + if(!userp) { + osi_Log1(afsd_logp, "ReceiveTran2Open user [%d] not resolvable", p->uid); + smb_FreeTran2Packet(outp); + return CM_ERROR_BADSMB; + } tidPathp = smb_GetTIDPath(vcp, p->tid); dscp = NULL; code = cm_NameI(cm_rootSCachep, pathp, - CM_FLAG_FOLLOW | CM_FLAG_CASEFOLD, - userp, tidPathp, &req, &scp); + CM_FLAG_FOLLOW | CM_FLAG_CASEFOLD, + userp, tidPathp, &req, &scp); if (code != 0) { code = cm_NameI(cm_rootSCachep, spacep->data, - CM_FLAG_FOLLOW | CM_FLAG_CASEFOLD, - userp, tidPathp, &req, &dscp); + CM_FLAG_FOLLOW | CM_FLAG_CASEFOLD, + userp, tidPathp, &req, &dscp); cm_FreeSpace(spacep); - if (code) { - cm_ReleaseUser(userp); + if (code) { + cm_ReleaseUser(userp); smb_FreeTran2Packet(outp); - return code; - } - - /* otherwise, scp points to the parent directory. Do a lookup, - * and truncate the file if we find it, otherwise we create the - * file. - */ - if (!lastNamep) lastNamep = pathp; - else lastNamep++; - code = cm_Lookup(dscp, lastNamep, CM_FLAG_CASEFOLD, userp, - &req, &scp); - if (code && code != CM_ERROR_NOSUCHFILE) { + return code; + } + + /* otherwise, scp points to the parent directory. Do a lookup, + * and truncate the file if we find it, otherwise we create the + * file. + */ + if (!lastNamep) lastNamep = pathp; + else lastNamep++; + code = cm_Lookup(dscp, lastNamep, CM_FLAG_CASEFOLD, userp, + &req, &scp); + if (code && code != CM_ERROR_NOSUCHFILE) { cm_ReleaseSCache(dscp); - cm_ReleaseUser(userp); + cm_ReleaseUser(userp); smb_FreeTran2Packet(outp); - return code; - } + return code; + } } - else { - cm_FreeSpace(spacep); + else { + cm_FreeSpace(spacep); } - - /* if we get here, if code is 0, the file exists and is represented by - * scp. Otherwise, we have to create it. - */ + + /* if we get here, if code is 0, the file exists and is represented by + * scp. Otherwise, we have to create it. + */ if (code == 0) { - code = cm_CheckOpen(scp, openMode, trunc, userp, &req); - if (code) { - if (dscp) cm_ReleaseSCache(dscp); - cm_ReleaseSCache(scp); - cm_ReleaseUser(userp); + code = cm_CheckOpen(scp, openMode, trunc, userp, &req); + if (code) { + if (dscp) cm_ReleaseSCache(dscp); + cm_ReleaseSCache(scp); + cm_ReleaseUser(userp); smb_FreeTran2Packet(outp); - return code; - } + return code; + } if (excl) { /* oops, file shouldn't be there */ - if (dscp) cm_ReleaseSCache(dscp); - cm_ReleaseSCache(scp); - cm_ReleaseUser(userp); + if (dscp) cm_ReleaseSCache(dscp); + cm_ReleaseSCache(scp); + cm_ReleaseUser(userp); smb_FreeTran2Packet(outp); - return CM_ERROR_EXISTS; - } + return CM_ERROR_EXISTS; + } if (trunc) { setAttr.mask = CM_ATTRMASK_LENGTH; - setAttr.length.LowPart = 0; - setAttr.length.HighPart = 0; + setAttr.length.LowPart = 0; + setAttr.length.HighPart = 0; code = cm_SetAttr(scp, &setAttr, userp, &req); - openAction = 3; /* truncated existing file */ - } - else openAction = 1; /* found existing file */ - } + openAction = 3; /* truncated existing file */ + } + else openAction = 1; /* found existing file */ + } else if (!(openFun & SMB_ATTR_DIRECTORY)) { /* don't create if not found */ - if (dscp) cm_ReleaseSCache(dscp); - osi_assert(scp == NULL); - cm_ReleaseUser(userp); + if (dscp) cm_ReleaseSCache(dscp); + osi_assert(scp == NULL); + cm_ReleaseUser(userp); smb_FreeTran2Packet(outp); - return CM_ERROR_NOSUCHFILE; - } - else { + return CM_ERROR_NOSUCHFILE; + } + else { osi_assert(dscp != NULL && scp == NULL); openAction = 2; /* created file */ setAttr.mask = CM_ATTRMASK_CLIENTMODTIME; smb_UnixTimeFromSearchTime(&setAttr.clientModTime, dosTime); - code = cm_Create(dscp, lastNamep, 0, &setAttr, &scp, userp, - &req); + 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) { + FILE_NOTIFY_CHANGE_FILE_NAME, + dscp, lastNamep, NULL, TRUE); + 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 - * fails, that means that the file was deleted after we - * started this call. - */ - code = cm_Lookup(dscp, lastNamep, CM_FLAG_CASEFOLD, - userp, &req, &scp); - if (code == 0) { - if (trunc) { + * creating it already, then we open it anyway. We + * don't bother retrying after this, since if this next + * fails, that means that the file was deleted after we + * started this call. + */ + code = cm_Lookup(dscp, lastNamep, CM_FLAG_CASEFOLD, + userp, &req, &scp); + if (code == 0) { + if (trunc) { setAttr.mask = CM_ATTRMASK_LENGTH; - setAttr.length.LowPart = 0; - setAttr.length.HighPart = 0; - code = cm_SetAttr(scp, &setAttr, userp, - &req); - } + setAttr.length.LowPart = 0; + setAttr.length.HighPart = 0; + code = cm_SetAttr(scp, &setAttr, userp, + &req); + } } /* lookup succeeded */ - } - } - + } + } + /* we don't need this any longer */ if (dscp) cm_ReleaseSCache(dscp); - if (code) { + if (code) { /* something went wrong creating or truncating the file */ - if (scp) cm_ReleaseSCache(scp); - cm_ReleaseUser(userp); + if (scp) cm_ReleaseSCache(scp); + cm_ReleaseUser(userp); smb_FreeTran2Packet(outp); - return code; - } - + return code; + } + /* make sure we're about to open a file */ if (scp->fileType != CM_SCACHETYPE_FILE) { cm_ReleaseSCache(scp); @@ -867,61 +865,61 @@ long smb_ReceiveTran2Open(smb_vc_t *vcp, smb_tran2Packet_t *p, smb_packet_t *op) return CM_ERROR_ISDIR; } - /* now all we have to do is open the file itself */ - fidp = smb_FindFID(vcp, 0, SMB_FLAG_CREATE); - osi_assert(fidp); - + /* now all we have to do is open the file itself */ + fidp = smb_FindFID(vcp, 0, SMB_FLAG_CREATE); + osi_assert(fidp); + /* save a pointer to the vnode */ - fidp->scp = scp; - + fidp->scp = scp; + /* compute open mode */ - if (openMode != 1) fidp->flags |= SMB_FID_OPENREAD; - if (openMode == 1 || openMode == 2) - fidp->flags |= SMB_FID_OPENWRITE; + if (openMode != 1) fidp->flags |= SMB_FID_OPENREAD; + if (openMode == 1 || openMode == 2) + fidp->flags |= SMB_FID_OPENWRITE; smb_ReleaseFID(fidp); - + cm_Open(scp, 0, userp); - /* copy out remainder of the parms */ + /* copy out remainder of the parms */ parmSlot = 0; outp->parmsp[parmSlot] = fidp->fid; parmSlot++; lock_ObtainMutex(&scp->mx); if (extraInfo) { - outp->parmsp[parmSlot] = smb_Attributes(scp); parmSlot++; + outp->parmsp[parmSlot] = smb_Attributes(scp); parmSlot++; smb_SearchTimeFromUnixTime(&dosTime, scp->clientModTime); - outp->parmsp[parmSlot] = dosTime & 0xffff; parmSlot++; - outp->parmsp[parmSlot] = (dosTime>>16) & 0xffff; parmSlot++; - outp->parmsp[parmSlot] = (unsigned short) (scp->length.LowPart & 0xffff); - parmSlot++; - outp->parmsp[parmSlot] = (unsigned short) ((scp->length.LowPart >> 16) & 0xffff); - parmSlot++; - outp->parmsp[parmSlot] = openMode; parmSlot++; - outp->parmsp[parmSlot] = 0; parmSlot++; /* file type 0 ==> normal file or dir */ - outp->parmsp[parmSlot] = 0; parmSlot++; /* IPC junk */ - } + outp->parmsp[parmSlot] = (unsigned short)(dosTime & 0xffff); parmSlot++; + outp->parmsp[parmSlot] = (unsigned short)((dosTime>>16) & 0xffff); parmSlot++; + outp->parmsp[parmSlot] = (unsigned short) (scp->length.LowPart & 0xffff); + parmSlot++; + outp->parmsp[parmSlot] = (unsigned short) ((scp->length.LowPart >> 16) & 0xffff); + parmSlot++; + outp->parmsp[parmSlot] = openMode; parmSlot++; + outp->parmsp[parmSlot] = 0; parmSlot++; /* file type 0 ==> normal file or dir */ + outp->parmsp[parmSlot] = 0; parmSlot++; /* IPC junk */ + } /* and the final "always present" stuff */ - outp->parmsp[parmSlot] = openAction; parmSlot++; + outp->parmsp[parmSlot] = openAction; parmSlot++; /* next write out the "unique" ID */ outp->parmsp[parmSlot] = (unsigned short) (scp->fid.vnode & 0xffff); parmSlot++; outp->parmsp[parmSlot] = (unsigned short) (scp->fid.volume & 0xffff); parmSlot++; - outp->parmsp[parmSlot] = 0; parmSlot++; - if (returnEALength) { + outp->parmsp[parmSlot] = 0; parmSlot++; + if (returnEALength) { outp->parmsp[parmSlot] = 0; parmSlot++; outp->parmsp[parmSlot] = 0; parmSlot++; - } + } lock_ReleaseMutex(&scp->mx); outp->totalData = 0; /* total # of data bytes */ - outp->totalParms = parmSlot * 2; /* shorts are two bytes */ + outp->totalParms = parmSlot * 2; /* shorts are two bytes */ smb_SendTran2Packet(vcp, outp, op); + + smb_FreeTran2Packet(outp); - smb_FreeTran2Packet(outp); - - cm_ReleaseUser(userp); - /* leave scp held since we put it in fidp->scp */ - return 0; -} + cm_ReleaseUser(userp); + /* leave scp held since we put it in fidp->scp */ + return 0; +} long smb_ReceiveTran2FindFirst(smb_vc_t *vcp, smb_tran2Packet_t *p, smb_packet_t *outp) { @@ -966,11 +964,11 @@ long smb_ReceiveTran2QFSInfo(smb_vc_t *vcp, smb_tran2Packet_t *p, smb_packet_t * case 2: /* volume info */ - qi.u.volumeInfo.vsn = 1234; - qi.u.volumeInfo.vnCount = 4; + qi.u.volumeInfo.vsn = 1234; + qi.u.volumeInfo.vnCount = 4; /* we're supposed to pad it out with zeroes to the end */ memset(&qi.u.volumeInfo.label, 0, sizeof(qi.u.volumeInfo.label)); - memcpy(qi.u.volumeInfo.label, "AFS", 4); + memcpy(qi.u.volumeInfo.label, "AFS", 4); break; case 0x102: @@ -1017,8 +1015,8 @@ long smb_ReceiveTran2QFSInfo(smb_vc_t *vcp, smb_tran2Packet_t *p, smb_packet_t * /* copy out return data, and set corresponding sizes */ outp->totalParms = 0; - outp->totalData = responseSize; - memcpy(outp->datap, &qi, responseSize); + outp->totalData = responseSize; + memcpy(outp->datap, &qi, responseSize); /* send and free the packets */ smb_SendTran2Packet(vcp, outp, op); @@ -1157,11 +1155,11 @@ long smb_ReceiveTran2QPathInfo(smb_vc_t *vcp, smb_tran2Packet_t *p, smb_packet_t } userp = smb_GetTran2User(vcp, p); - if(!userp) { - osi_Log1(afsd_logp, "ReceiveTran2QPathInfo unable to resolve user [%d]", p->uid); - smb_FreeTran2Packet(outp); - return CM_ERROR_BADSMB; - } + if(!userp) { + osi_Log1(afsd_logp, "ReceiveTran2QPathInfo unable to resolve user [%d]", p->uid); + smb_FreeTran2Packet(outp); + return CM_ERROR_BADSMB; + } tidPathp = smb_GetTIDPath(vcp, p->tid); @@ -1183,35 +1181,36 @@ long smb_ReceiveTran2QPathInfo(smb_vc_t *vcp, smb_tran2Packet_t *p, smb_packet_t spacep = cm_GetSpace(); smb_StripLastComponent(spacep->data, &lastComp, (char *)(&p->parmsp[3])); - if(lastComp) { - if (strcmp(lastComp, "\\desktop.ini") == 0) { - code = cm_NameI(cm_rootSCachep, spacep->data, - CM_FLAG_CASEFOLD - | CM_FLAG_DIRSEARCH - | CM_FLAG_FOLLOW, - userp, tidPathp, &req, &dscp); - if (code == 0) { - if (dscp->fileType == CM_SCACHETYPE_MOUNTPOINT - && !dscp->mountRootFidp) - code = CM_ERROR_NOSUCHFILE; - else if (dscp->fileType == CM_SCACHETYPE_DIRECTORY) { - cm_buf_t *bp = buf_Find(dscp, &hzero); - if (bp) - buf_Release(bp); - else - code = CM_ERROR_NOSUCHFILE; - } - cm_ReleaseSCache(dscp); - if (code) { - cm_FreeSpace(spacep); - cm_ReleaseUser(userp); - smb_SendTran2Error(vcp, p, opx, code); - smb_FreeTran2Packet(outp); - return 0; - } - } - } - } + /* Make sure that lastComp is not NULL */ + if (lastComp) { + if (strcmp(lastComp, "\\desktop.ini") == 0) { + code = cm_NameI(cm_rootSCachep, spacep->data, + CM_FLAG_CASEFOLD + | CM_FLAG_DIRSEARCH + | CM_FLAG_FOLLOW, + userp, tidPathp, &req, &dscp); + if (code == 0) { + if (dscp->fileType == CM_SCACHETYPE_MOUNTPOINT + && !dscp->mountRootFidp) + code = CM_ERROR_NOSUCHFILE; + else if (dscp->fileType == CM_SCACHETYPE_DIRECTORY) { + cm_buf_t *bp = buf_Find(dscp, &hzero); + if (bp) + buf_Release(bp); + else + code = CM_ERROR_NOSUCHFILE; + } + cm_ReleaseSCache(dscp); + if (code) { + cm_FreeSpace(spacep); + cm_ReleaseUser(userp); + smb_SendTran2Error(vcp, p, opx, code); + smb_FreeTran2Packet(outp); + return 0; + } + } + } + } cm_FreeSpace(spacep); } @@ -1316,7 +1315,7 @@ long smb_ReceiveTran2QFileInfo(smb_vc_t *vcp, smb_tran2Packet_t *p, smb_packet_t int nbytesRequired; unsigned short fid; cm_user_t *userp; - smb_fid_t *fidp; + smb_fid_t *fidp; cm_scache_t *scp; char *op; long code; @@ -1324,8 +1323,8 @@ long smb_ReceiveTran2QFileInfo(smb_vc_t *vcp, smb_tran2Packet_t *p, smb_packet_t cm_InitReq(&req); - fid = p->parmsp[0]; - fidp = smb_FindFID(vcp, fid, 0); + fid = p->parmsp[0]; + fidp = smb_FindFID(vcp, fid, 0); if (fidp == NULL) { smb_SendTran2Error(vcp, p, opx, CM_ERROR_BADFD); @@ -1339,7 +1338,7 @@ long smb_ReceiveTran2QFileInfo(smb_vc_t *vcp, smb_tran2Packet_t *p, smb_packet_t else if (infoLevel == 0x104) nbytesRequired = 6; else { osi_Log2(afsd_logp, "Bad Tran2 op 0x%x infolevel 0x%x", - p->opcode, infoLevel); + p->opcode, infoLevel); smb_SendTran2Error(vcp, p, opx, CM_ERROR_INVAL); smb_ReleaseFID(fidp); return 0; @@ -1355,16 +1354,16 @@ long smb_ReceiveTran2QFileInfo(smb_vc_t *vcp, smb_tran2Packet_t *p, smb_packet_t outp->totalData = nbytesRequired; userp = smb_GetTran2User(vcp, p); - if(!userp) { - osi_Log1(afsd_logp, "ReceiveTran2QFileInfo unable to resolve user [%d]", p->uid); - code = CM_ERROR_BADSMB; - goto done; - } + if(!userp) { + osi_Log1(afsd_logp, "ReceiveTran2QFileInfo unable to resolve user [%d]", p->uid); + code = CM_ERROR_BADSMB; + goto done; + } scp = fidp->scp; lock_ObtainMutex(&scp->mx); code = cm_SyncOp(scp, NULL, userp, &req, 0, - CM_SCACHESYNC_NEEDCALLBACK | CM_SCACHESYNC_GETSTATUS); + CM_SCACHESYNC_NEEDCALLBACK | CM_SCACHESYNC_GETSTATUS); if (code) goto done; /* now we have the status in the cache entry, and everything is locked. @@ -1432,7 +1431,7 @@ long smb_ReceiveTran2SetFileInfo(smb_vc_t *vcp, smb_tran2Packet_t *p, smb_packet cm_InitReq(&req); - fid = p->parmsp[0]; + fid = p->parmsp[0]; fidp = smb_FindFID(vcp, fid, 0); if (fidp == NULL) { @@ -1469,11 +1468,11 @@ long smb_ReceiveTran2SetFileInfo(smb_vc_t *vcp, smb_tran2Packet_t *p, smb_packet outp->totalData = 0; userp = smb_GetTran2User(vcp, p); - if(!userp) { - osi_Log1(afsd_logp,"ReceiveTran2SetFileInfo unable to resolve user [%d]", p->uid); - code = CM_ERROR_BADSMB; - goto done; - } + if(!userp) { + osi_Log1(afsd_logp,"ReceiveTran2SetFileInfo unable to resolve user [%d]", p->uid); + code = CM_ERROR_BADSMB; + goto done; + } scp = fidp->scp; @@ -1487,8 +1486,8 @@ long smb_ReceiveTran2SetFileInfo(smb_vc_t *vcp, smb_tran2Packet_t *p, smb_packet */ lock_ObtainMutex(&scp->mx); code = cm_SyncOp(scp, NULL, userp, &req, 0, - CM_SCACHESYNC_GETSTATUS - | CM_SCACHESYNC_NEEDCALLBACK); + CM_SCACHESYNC_GETSTATUS + | CM_SCACHESYNC_NEEDCALLBACK); if (code) { lock_ReleaseMutex(&scp->mx); goto done; @@ -1496,22 +1495,20 @@ long smb_ReceiveTran2SetFileInfo(smb_vc_t *vcp, smb_tran2Packet_t *p, smb_packet /* prepare for setattr call */ attr.mask = 0; + lastMod = *((FILETIME *)(p->datap + 16)); - /* when called as result of move a b, lastMod is (-1, -1). If the check for -1 - is not present, timestamp - of the resulting file will be 1969 (-1) - */ - - if (LargeIntegerNotEqualToZero(*((LARGE_INTEGER *)&lastMod)) && - lastMod.dwLowDateTime != -1 && - lastMod.dwHighDateTime != -1) - { - attr.mask |= CM_ATTRMASK_CLIENTMODTIME; - smb_UnixTimeFromLargeSearchTime(&attr.clientModTime, - &lastMod); - fidp->flags |= SMB_FID_MTIMESETDONE; + /* when called as result of move a b, lastMod is (-1, -1). + * If the check for -1 is not present, timestamp + * of the resulting file will be 1969 (-1) + */ + if (LargeIntegerNotEqualToZero(*((LARGE_INTEGER *)&lastMod)) && + lastMod.dwLowDateTime != -1 && lastMod.dwHighDateTime != -1) { + attr.mask |= CM_ATTRMASK_CLIENTMODTIME; + smb_UnixTimeFromLargeSearchTime(&attr.clientModTime, + &lastMod); + fidp->flags |= SMB_FID_MTIMESETDONE; } - + attribute = *((u_long *)(p->datap + 32)); if (attribute != 0) { if ((scp->unixModeBits & 0222) @@ -1668,10 +1665,9 @@ long smb_ApplyV3DirListPatches(cm_scache_t *dscp, /* Copy attributes */ lattr = smb_ExtAttributes(scp); - /* merge in hidden (dot file) attribute */ - if( patchp->flags & SMB_DIRLISTPATCH_DOTFILE ) - lattr |= SMB_ATTR_HIDDEN; - + /* merge in hidden (dot file) attribute */ + if( patchp->flags & SMB_DIRLISTPATCH_DOTFILE ) + lattr |= SMB_ATTR_HIDDEN; *((u_long *)dptr) = lattr; dptr += 4; } @@ -1719,10 +1715,9 @@ long smb_ApplyV3DirListPatches(cm_scache_t *dscp, /* finally copy out attributes as short */ attr = smb_Attributes(scp); - /* merge in hidden (dot file) attribute */ - if( patchp->flags & SMB_DIRLISTPATCH_DOTFILE ) - attr |= SMB_ATTR_HIDDEN; - + /* merge in hidden (dot file) attribute */ + if( patchp->flags & SMB_DIRLISTPATCH_DOTFILE ) + attr |= SMB_ATTR_HIDDEN; *dptr++ = attr & 0xff; *dptr++ = (attr >> 8) & 0xff; } @@ -1879,827 +1874,826 @@ int smb_V3MatchMask(char *namep, char *maskp, int flags) long smb_ReceiveTran2SearchDir(smb_vc_t *vcp, smb_tran2Packet_t *p, smb_packet_t *opx) { int attribute; - long nextCookie; - char *tp; - long code; - char *pathp; - cm_dirEntry_t *dep; - int maxCount; - smb_dirListPatch_t *dirListPatchesp; - smb_dirListPatch_t *curPatchp; - cm_buf_t *bufferp; - long temp; - long orbytes; /* # of bytes in this output record */ - long ohbytes; /* # of bytes, except file name */ - long onbytes; /* # of bytes in name, incl. term. null */ - osi_hyper_t dirLength; - osi_hyper_t bufferOffset; - osi_hyper_t curOffset; - osi_hyper_t thyper; - smb_dirSearch_t *dsp; - cm_scache_t *scp; - long entryInDir; - long entryInBuffer; + long nextCookie; + char *tp; + long code; + char *pathp; + cm_dirEntry_t *dep; + int maxCount; + smb_dirListPatch_t *dirListPatchesp; + smb_dirListPatch_t *curPatchp; + cm_buf_t *bufferp; + long temp; + long orbytes; /* # of bytes in this output record */ + long ohbytes; /* # of bytes, except file name */ + long onbytes; /* # of bytes in name, incl. term. null */ + osi_hyper_t dirLength; + osi_hyper_t bufferOffset; + osi_hyper_t curOffset; + osi_hyper_t thyper; + smb_dirSearch_t *dsp; + cm_scache_t *scp; + long entryInDir; + long entryInBuffer; cm_pageHeader_t *pageHeaderp; - cm_user_t *userp = NULL; - int slotInPage; - int returnedNames; - long nextEntryCookie; - int numDirChunks; /* # of 32 byte dir chunks in this entry */ - char *op; /* output data ptr */ + cm_user_t *userp = NULL; + int slotInPage; + int returnedNames; + long nextEntryCookie; + int numDirChunks; /* # of 32 byte dir chunks in this entry */ + char *op; /* output data ptr */ char *origOp; /* original value of op */ - cm_space_t *spacep; /* for pathname buffer */ - long maxReturnData; /* max # of return data */ - long maxReturnParms; /* max # of return parms */ - long bytesInBuffer; /* # data bytes in the output buffer */ - int starPattern; - char *maskp; /* mask part of path */ - int infoLevel; - int searchFlags; - int eos; - smb_tran2Packet_t *outp; /* response packet */ + cm_space_t *spacep; /* for pathname buffer */ + long maxReturnData; /* max # of return data */ + long maxReturnParms; /* max # of return parms */ + long bytesInBuffer; /* # data bytes in the output buffer */ + int starPattern; + char *maskp; /* mask part of path */ + int infoLevel; + int searchFlags; + int eos; + smb_tran2Packet_t *outp; /* response packet */ char *tidPathp; int align; char shortName[13]; /* 8.3 name if needed */ int NeedShortName; char *shortNameEnd; - int fileType; - cm_fid_t fid; - - cm_req_t req; + int fileType; + cm_fid_t fid; + + cm_req_t req; cm_InitReq(&req); eos = 0; if (p->opcode == 1) { /* find first; obtain basic parameters from request */ - attribute = p->parmsp[0]; - maxCount = p->parmsp[1]; - infoLevel = p->parmsp[3]; - searchFlags = p->parmsp[2]; - dsp = smb_NewDirSearch(1); - dsp->attribute = attribute; - pathp = ((char *) p->parmsp) + 12; /* points to path */ - nextCookie = 0; - maskp = strrchr(pathp, '\\'); - if (maskp == NULL) maskp = pathp; + attribute = p->parmsp[0]; + maxCount = p->parmsp[1]; + infoLevel = p->parmsp[3]; + searchFlags = p->parmsp[2]; + dsp = smb_NewDirSearch(1); + dsp->attribute = attribute; + pathp = ((char *) p->parmsp) + 12; /* points to path */ + nextCookie = 0; + maskp = strrchr(pathp, '\\'); + if (maskp == NULL) maskp = pathp; else maskp++; /* skip over backslash */ - strcpy(dsp->mask, maskp); /* and save mask */ - /* track if this is likely to match a lot of entries */ - starPattern = smb_V3IsStarMask(maskp); - } - else { + strcpy(dsp->mask, maskp); /* and save mask */ + /* track if this is likely to match a lot of entries */ + starPattern = smb_V3IsStarMask(maskp); + } + else { osi_assert(p->opcode == 2); - /* find next; obtain basic parameters from request or open dir file */ - dsp = smb_FindDirSearch(p->parmsp[0]); - if (!dsp) return CM_ERROR_BADFD; - attribute = dsp->attribute; - maxCount = p->parmsp[1]; - infoLevel = p->parmsp[2]; - searchFlags = p->parmsp[5]; - pathp = NULL; - nextCookie = p->parmsp[3] | (p->parmsp[4] << 16); - maskp = dsp->mask; + /* find next; obtain basic parameters from request or open dir file */ + dsp = smb_FindDirSearch(p->parmsp[0]); + if (!dsp) return CM_ERROR_BADFD; + attribute = dsp->attribute; + maxCount = p->parmsp[1]; + infoLevel = p->parmsp[2]; + searchFlags = p->parmsp[5]; + pathp = NULL; + nextCookie = p->parmsp[3] | (p->parmsp[4] << 16); + maskp = dsp->mask; starPattern = 1; /* assume, since required a Find Next */ - } + } osi_Log4(afsd_logp, - "T2 search dir attr 0x%x, info level %d, max count %d, flags 0x%x", - attribute, infoLevel, maxCount, searchFlags); + "T2 search dir attr 0x%x, info level %d, max count %d, flags 0x%x", + attribute, infoLevel, maxCount, searchFlags); osi_Log2(afsd_logp, "...T2 search op %d, nextCookie 0x%x", - p->opcode, nextCookie); + p->opcode, nextCookie); if (infoLevel >= 0x101) searchFlags &= ~4; /* no resume keys */ - dirListPatchesp = NULL; + dirListPatchesp = NULL; maxReturnData = p->maxReturnData; - if (p->opcode == 1) /* find first */ - maxReturnParms = 10; /* bytes */ + if (p->opcode == 1) /* find first */ + maxReturnParms = 10; /* bytes */ else - maxReturnParms = 8; /* bytes */ + maxReturnParms = 8; /* bytes */ #ifndef CM_CONFIG_MULTITRAN2RESPONSES - if (maxReturnData > 6000) maxReturnData = 6000; + if (maxReturnData > 6000) maxReturnData = 6000; #endif /* CM_CONFIG_MULTITRAN2RESPONSES */ outp = smb_GetTran2ResponsePacket(vcp, p, opx, maxReturnParms, - maxReturnData); - - osi_Log1(afsd_logp, "T2 receive search dir %s", - osi_LogSaveString(afsd_logp, pathp)); - - /* bail out if request looks bad */ - if (p->opcode == 1 && !pathp) { - smb_ReleaseDirSearch(dsp); - smb_FreeTran2Packet(outp); - return CM_ERROR_BADSMB; - } + maxReturnData); + osi_Log1(afsd_logp, "T2 receive search dir %s", + osi_LogSaveString(afsd_logp, pathp)); + + /* bail out if request looks bad */ + if (p->opcode == 1 && !pathp) { + smb_ReleaseDirSearch(dsp); + smb_FreeTran2Packet(outp); + return CM_ERROR_BADSMB; + } + osi_Log2(afsd_logp, "T2 dir search cookie 0x%x, connection %d", - nextCookie, dsp->cookie); - - userp = smb_GetTran2User(vcp, p); - if(!userp) { - osi_Log1(afsd_logp, "T2 dir search unable to resolve user [%d]", p->uid); - smb_ReleaseDirSearch(dsp); - smb_FreeTran2Packet(outp); - return CM_ERROR_BADSMB; - } + nextCookie, dsp->cookie); + + userp = smb_GetTran2User(vcp, p); + if (!userp) { + osi_Log1(afsd_logp, "T2 dir search unable to resolve user [%d]", p->uid); + smb_ReleaseDirSearch(dsp); + smb_FreeTran2Packet(outp); + return CM_ERROR_BADSMB; + } /* try to get the vnode for the path name next */ lock_ObtainMutex(&dsp->mx); if (dsp->scp) { scp = dsp->scp; - cm_HoldSCache(scp); - code = 0; - } - else { - spacep = cm_GetSpace(); - smb_StripLastComponent(spacep->data, NULL, pathp); - lock_ReleaseMutex(&dsp->mx); + cm_HoldSCache(scp); + code = 0; + } + else { + spacep = cm_GetSpace(); + smb_StripLastComponent(spacep->data, NULL, pathp); + lock_ReleaseMutex(&dsp->mx); tidPathp = smb_GetTIDPath(vcp, p->tid); - code = cm_NameI(cm_rootSCachep, spacep->data, - CM_FLAG_FOLLOW | CM_FLAG_CASEFOLD, - userp, tidPathp, &req, &scp); - cm_FreeSpace(spacep); + code = cm_NameI(cm_rootSCachep, spacep->data, + CM_FLAG_FOLLOW | CM_FLAG_CASEFOLD, + userp, tidPathp, &req, &scp); + cm_FreeSpace(spacep); - lock_ObtainMutex(&dsp->mx); + lock_ObtainMutex(&dsp->mx); if (code == 0) { - if (dsp->scp != 0) cm_ReleaseSCache(dsp->scp); + if (dsp->scp != 0) cm_ReleaseSCache(dsp->scp); dsp->scp = scp; /* we need one hold for the entry we just stored into, - * and one for our own processing. When we're done - * with this function, we'll drop the one for our own - * processing. We held it once from the namei call, - * and so we do another hold now. - */ - cm_HoldSCache(scp); - lock_ObtainMutex(&scp->mx); - if ((scp->flags & CM_SCACHEFLAG_BULKSTATTING) == 0 - && LargeIntegerGreaterOrEqualToZero(scp->bulkStatProgress)) { - scp->flags |= CM_SCACHEFLAG_BULKSTATTING; - dsp->flags |= SMB_DIRSEARCH_BULKST; - } - lock_ReleaseMutex(&scp->mx); - } - } + * and one for our own processing. When we're done + * with this function, we'll drop the one for our own + * processing. We held it once from the namei call, + * and so we do another hold now. + */ + cm_HoldSCache(scp); + lock_ObtainMutex(&scp->mx); + if ((scp->flags & CM_SCACHEFLAG_BULKSTATTING) == 0 + && LargeIntegerGreaterOrEqualToZero(scp->bulkStatProgress)) { + scp->flags |= CM_SCACHEFLAG_BULKSTATTING; + dsp->flags |= SMB_DIRSEARCH_BULKST; + } + lock_ReleaseMutex(&scp->mx); + } + } lock_ReleaseMutex(&dsp->mx); - if (code) { + if (code) { cm_ReleaseUser(userp); - smb_FreeTran2Packet(outp); + smb_FreeTran2Packet(outp); smb_DeleteDirSearch(dsp); smb_ReleaseDirSearch(dsp); - return code; - } + return code; + } - /* get the directory size */ + /* get the directory size */ lock_ObtainMutex(&scp->mx); - code = cm_SyncOp(scp, NULL, userp, &req, 0, - CM_SCACHESYNC_NEEDCALLBACK | CM_SCACHESYNC_GETSTATUS); + code = cm_SyncOp(scp, NULL, userp, &req, 0, + CM_SCACHESYNC_NEEDCALLBACK | CM_SCACHESYNC_GETSTATUS); if (code) { lock_ReleaseMutex(&scp->mx); - cm_ReleaseSCache(scp); - cm_ReleaseUser(userp); - smb_FreeTran2Packet(outp); + cm_ReleaseSCache(scp); + cm_ReleaseUser(userp); + smb_FreeTran2Packet(outp); smb_DeleteDirSearch(dsp); smb_ReleaseDirSearch(dsp); - return code; - } - - dirLength = scp->length; - bufferp = NULL; - bufferOffset.LowPart = bufferOffset.HighPart = 0; - curOffset.HighPart = 0; - curOffset.LowPart = nextCookie; + return code; + } + + dirLength = scp->length; + bufferp = NULL; + bufferOffset.LowPart = bufferOffset.HighPart = 0; + curOffset.HighPart = 0; + curOffset.LowPart = nextCookie; origOp = outp->datap; - code = 0; - returnedNames = 0; - bytesInBuffer = 0; - while (1) { + code = 0; + returnedNames = 0; + bytesInBuffer = 0; + while (1) { op = origOp; if (searchFlags & 4) /* skip over resume key */ op += 4; /* make sure that curOffset.LowPart doesn't point to the first - * 32 bytes in the 2nd through last dir page, and that it doesn't - * point at the first 13 32-byte chunks in the first dir page, - * since those are dir and page headers, and don't contain useful - * information. - */ + * 32 bytes in the 2nd through last dir page, and that it doesn't + * point at the first 13 32-byte chunks in the first dir page, + * since those are dir and page headers, and don't contain useful + * information. + */ temp = curOffset.LowPart & (2048-1); - if (curOffset.HighPart == 0 && curOffset.LowPart < 2048) { + if (curOffset.HighPart == 0 && curOffset.LowPart < 2048) { /* we're in the first page */ - if (temp < 13*32) temp = 13*32; + if (temp < 13*32) temp = 13*32; } else { /* we're in a later dir page */ - if (temp < 32) temp = 32; - } - - /* make sure the low order 5 bits are zero */ - temp &= ~(32-1); - - /* now put temp bits back ito curOffset.LowPart */ - curOffset.LowPart &= ~(2048-1); - curOffset.LowPart |= temp; - - /* check if we've passed the dir's EOF */ - if (LargeIntegerGreaterThanOrEqualTo(curOffset, dirLength)) { - eos = 1; - break; - } - - /* check if we've returned all the names that will fit in the - * response packet; we check return count as well as the number - * of bytes requested. We check the # of bytes after we find - * the dir entry, since we'll need to check its size. - */ - if (returnedNames >= maxCount) { - break; - } - - /* see if we can use the bufferp we have now; compute in which - * page the current offset would be, and check whether that's - * the offset of the buffer we have. If not, get the buffer. - */ - thyper.HighPart = curOffset.HighPart; - thyper.LowPart = curOffset.LowPart & ~(buf_bufferSize-1); - if (!bufferp || !LargeIntegerEqualTo(thyper, bufferOffset)) { + if (temp < 32) temp = 32; + } + + /* make sure the low order 5 bits are zero */ + temp &= ~(32-1); + + /* now put temp bits back ito curOffset.LowPart */ + curOffset.LowPart &= ~(2048-1); + curOffset.LowPart |= temp; + + /* check if we've passed the dir's EOF */ + if (LargeIntegerGreaterThanOrEqualTo(curOffset, dirLength)) { + eos = 1; + break; + } + + /* check if we've returned all the names that will fit in the + * response packet; we check return count as well as the number + * of bytes requested. We check the # of bytes after we find + * the dir entry, since we'll need to check its size. + */ + if (returnedNames >= maxCount) { + break; + } + + /* see if we can use the bufferp we have now; compute in which + * page the current offset would be, and check whether that's + * the offset of the buffer we have. If not, get the buffer. + */ + thyper.HighPart = curOffset.HighPart; + thyper.LowPart = curOffset.LowPart & ~(buf_bufferSize-1); + if (!bufferp || !LargeIntegerEqualTo(thyper, bufferOffset)) { /* wrong buffer */ - if (bufferp) { - buf_Release(bufferp); - bufferp = NULL; - } + if (bufferp) { + buf_Release(bufferp); + bufferp = NULL; + } lock_ReleaseMutex(&scp->mx); lock_ObtainRead(&scp->bufCreateLock); - code = buf_Get(scp, &thyper, &bufferp); + code = buf_Get(scp, &thyper, &bufferp); lock_ReleaseRead(&scp->bufCreateLock); /* now, if we're doing a star match, do bulk fetching - * of all of the status info for files in the dir. - */ - if (starPattern) { + * of all of the status info for files in the dir. + */ + if (starPattern) { smb_ApplyV3DirListPatches(scp, &dirListPatchesp, - infoLevel, userp, - &req); - if ((dsp->flags & SMB_DIRSEARCH_BULKST) - && LargeIntegerGreaterThanOrEqualTo( - thyper, scp->bulkStatProgress)) { - /* Don't bulk stat if risking timeout */ - int now = GetCurrentTime(); - if (now - req.startTime > 5000) { - scp->bulkStatProgress = thyper; - scp->flags &= ~CM_SCACHEFLAG_BULKSTATTING; - dsp->flags &= ~SMB_DIRSEARCH_BULKST; - } else - cm_TryBulkStat(scp, &thyper, - userp, &req); - } + infoLevel, userp, + &req); + if ((dsp->flags & SMB_DIRSEARCH_BULKST) + && LargeIntegerGreaterThanOrEqualTo( + thyper, scp->bulkStatProgress)) { + /* Don't bulk stat if risking timeout */ + int now = GetCurrentTime(); + if (now - req.startTime > 5000) { + scp->bulkStatProgress = thyper; + scp->flags &= ~CM_SCACHEFLAG_BULKSTATTING; + dsp->flags &= ~SMB_DIRSEARCH_BULKST; + } else + cm_TryBulkStat(scp, &thyper, + userp, &req); + } } - lock_ObtainMutex(&scp->mx); - if (code) break; - bufferOffset = thyper; + lock_ObtainMutex(&scp->mx); + if (code) break; + bufferOffset = thyper; - /* now get the data in the cache */ - while (1) { + /* now get the data in the cache */ + while (1) { code = cm_SyncOp(scp, bufferp, userp, &req, PRSFS_LOOKUP, - CM_SCACHESYNC_NEEDCALLBACK + CM_SCACHESYNC_NEEDCALLBACK | CM_SCACHESYNC_READ); if (code) break; - - if (cm_HaveBuffer(scp, bufferp, 0)) break; - - /* otherwise, load the buffer and try again */ - code = cm_GetBuffer(scp, bufferp, NULL, userp, - &req); - if (code) break; - } - if (code) { + + if (cm_HaveBuffer(scp, bufferp, 0)) break; + + /* otherwise, load the buffer and try again */ + code = cm_GetBuffer(scp, bufferp, NULL, userp, + &req); + if (code) break; + } + if (code) { buf_Release(bufferp); - bufferp = NULL; - break; + bufferp = NULL; + break; } - } /* if (wrong buffer) ... */ - - /* now we have the buffer containing the entry we're interested - * in; copy it out if it represents a non-deleted entry. - */ + } /* if (wrong buffer) ... */ + + /* now we have the buffer containing the entry we're interested + * in; copy it out if it represents a non-deleted entry. + */ entryInDir = curOffset.LowPart & (2048-1); - entryInBuffer = curOffset.LowPart & (buf_bufferSize - 1); + entryInBuffer = curOffset.LowPart & (buf_bufferSize - 1); /* page header will help tell us which entries are free. Page - * header can change more often than once per buffer, since - * AFS 3 dir page size may be less than (but not more than) - * a buffer package buffer. - */ + * header can change more often than once per buffer, since + * AFS 3 dir page size may be less than (but not more than) + * a buffer package buffer. + */ /* only look intra-buffer */ temp = curOffset.LowPart & (buf_bufferSize - 1); - temp &= ~(2048 - 1); /* turn off intra-page bits */ + temp &= ~(2048 - 1); /* turn off intra-page bits */ pageHeaderp = (cm_pageHeader_t *) (bufferp->datap + temp); /* now determine which entry we're looking at in the page. - * If it is free (there's a free bitmap at the start of the - * dir), we should skip these 32 bytes. - */ - slotInPage = (entryInDir & 0x7e0) >> 5; - if (!(pageHeaderp->freeBitmap[slotInPage>>3] - & (1 << (slotInPage & 0x7)))) { + * If it is free (there's a free bitmap at the start of the + * dir), we should skip these 32 bytes. + */ + slotInPage = (entryInDir & 0x7e0) >> 5; + if (!(pageHeaderp->freeBitmap[slotInPage>>3] + & (1 << (slotInPage & 0x7)))) { /* this entry is free */ - numDirChunks = 1; /* only skip this guy */ - goto nextEntry; - } + numDirChunks = 1; /* only skip this guy */ + goto nextEntry; + } tp = bufferp->datap + entryInBuffer; - dep = (cm_dirEntry_t *) tp; /* now points to AFS3 dir entry */ + dep = (cm_dirEntry_t *) tp; /* now points to AFS3 dir entry */ - /* while we're here, compute the next entry's location, too, - * since we'll need it when writing out the cookie into the dir - * listing stream. - * - * XXXX Probably should do more sanity checking. - */ + /* while we're here, compute the next entry's location, too, + * since we'll need it when writing out the cookie into the dir + * listing stream. + * + * XXXX Probably should do more sanity checking. + */ numDirChunks = cm_NameEntries(dep->name, &onbytes); - - /* compute offset of cookie representing next entry */ - nextEntryCookie = curOffset.LowPart - + (CM_DIR_CHUNKSIZE * numDirChunks); + + /* compute offset of cookie representing next entry */ + nextEntryCookie = curOffset.LowPart + + (CM_DIR_CHUNKSIZE * numDirChunks); /* Need 8.3 name? */ NeedShortName = 0; if (infoLevel == 0x104 - && dep->fid.vnode != 0 - && !cm_Is8Dot3(dep->name)) { - cm_Gen8Dot3Name(dep, shortName, &shortNameEnd); - NeedShortName = 1; + && dep->fid.vnode != 0 + && !cm_Is8Dot3(dep->name)) { + cm_Gen8Dot3Name(dep, shortName, &shortNameEnd); + NeedShortName = 1; + } + + if (dep->fid.vnode != 0 + && (smb_V3MatchMask(dep->name, maskp, CM_FLAG_CASEFOLD) + || (NeedShortName + && smb_V3MatchMask(shortName, maskp, + CM_FLAG_CASEFOLD)))) { + + /* Eliminate entries that don't match requested + attributes */ + if (smb_hideDotFiles && !(dsp->attribute & SMB_ATTR_HIDDEN) && + smb_IsDotFile(dep->name)) + goto nextEntry; /* no hidden files */ + + if (!(dsp->attribute & SMB_ATTR_DIRECTORY)) /* no directories */ + { + /* We have already done the cm_TryBulkStat above */ + fid.cell = scp->fid.cell; + fid.volume = scp->fid.volume; + fid.vnode = ntohl(dep->fid.vnode); + fid.unique = ntohl(dep->fid.unique); + fileType = cm_FindFileType(&fid); + /*osi_Log2(afsd_logp, "smb_ReceiveTran2SearchDir: file %s " + "has filetype %d", dep->name, + fileType);*/ + if (fileType == CM_SCACHETYPE_DIRECTORY) + goto nextEntry; + } + + /* finally check if this name will fit */ + + /* standard dir entry stuff */ + if (infoLevel < 0x101) + ohbytes = 23; /* pre-NT */ + else if (infoLevel == 0x103) + ohbytes = 12; /* NT names only */ + else + ohbytes = 64; /* NT */ + + if (infoLevel == 0x104) + ohbytes += 26; /* Short name & length */ + + if (searchFlags & 4) { + ohbytes += 4; /* if resume key required */ } - if (dep->fid.vnode != 0 - && (smb_V3MatchMask(dep->name, maskp, CM_FLAG_CASEFOLD) - || (NeedShortName - && smb_V3MatchMask(shortName, maskp, - CM_FLAG_CASEFOLD)))) { - - /* Eliminate entries that don't match requested - attributes */ - if (smb_hideDotFiles && !(dsp->attribute & SMB_ATTR_HIDDEN) && smb_IsDotFile(dep->name)) - goto nextEntry; /* no hidden files */ - - if (!(dsp->attribute & SMB_ATTR_DIRECTORY)) /* no directories */ - { - /* We have already done the cm_TryBulkStat above */ - fid.cell = scp->fid.cell; - fid.volume = scp->fid.volume; - fid.vnode = ntohl(dep->fid.vnode); - fid.unique = ntohl(dep->fid.unique); - fileType = cm_FindFileType(&fid); - /*osi_Log2(afsd_logp, "smb_ReceiveTran2SearchDir: file %s " - "has filetype %d", dep->name, - fileType);*/ - if (fileType == CM_SCACHETYPE_DIRECTORY) - goto nextEntry; - } - - /* finally check if this name will fit */ - - /* standard dir entry stuff */ - if (infoLevel < 0x101) - ohbytes = 23; /* pre-NT */ - else if (infoLevel == 0x103) - ohbytes = 12; /* NT names only */ - else - ohbytes = 64; /* NT */ + if (infoLevel != 1 + && infoLevel != 0x101 + && infoLevel != 0x103) + ohbytes += 4; /* EASIZE */ - if (infoLevel == 0x104) - ohbytes += 26; /* Short name & length */ + /* add header to name & term. null */ + orbytes = onbytes + ohbytes + 1; - if (searchFlags & 4) { - ohbytes += 4; /* if resume key required */ - } + /* now, we round up the record to a 4 byte alignment, + * and we make sure that we have enough room here for + * even the aligned version (so we don't have to worry + * about an * overflow when we pad things out below). + * That's the reason for the alignment arithmetic below. + */ + if (infoLevel >= 0x101) + align = (4 - (orbytes & 3)) & 3; + else + align = 0; + if (orbytes + bytesInBuffer + align > maxReturnData) + break; - if (infoLevel != 1 - && infoLevel != 0x101 - && infoLevel != 0x103) - ohbytes += 4; /* EASIZE */ + /* this is one of the entries to use: it is not deleted + * and it matches the star pattern we're looking for. + * Put out the name, preceded by its length. + */ + /* First zero everything else */ + memset(origOp, 0, ohbytes); - /* add header to name & term. null */ - orbytes = onbytes + ohbytes + 1; + if (infoLevel <= 0x101) + *(origOp + ohbytes - 1) = (unsigned char) onbytes; + else if (infoLevel == 0x103) + *((u_long *)(op + 8)) = onbytes; + else + *((u_long *)(op + 60)) = onbytes; + strcpy(origOp+ohbytes, dep->name); + + /* Short name if requested and needed */ + if (infoLevel == 0x104) { + if (NeedShortName) { + strcpy(op + 70, shortName); + *(op + 68) = shortNameEnd - shortName; + } + } - /* now, we round up the record to a 4 byte alignment, - * and we make sure that we have enough room here for - * even the aligned version (so we don't have to worry - * about an * overflow when we pad things out below). - * That's the reason for the alignment arithmetic below. - */ - if (infoLevel >= 0x101) - align = (4 - (orbytes & 3)) & 3; - else - align = 0; - if (orbytes + bytesInBuffer + align > maxReturnData) - break; + /* now, adjust the # of entries copied */ + returnedNames++; - /* this is one of the entries to use: it is not deleted - * and it matches the star pattern we're looking for. - * Put out the name, preceded by its length. - */ - /* First zero everything else */ - memset(origOp, 0, ohbytes); + /* NextEntryOffset and FileIndex */ + if (infoLevel >= 101) { + int entryOffset = orbytes + align; + *((u_long *)op) = entryOffset; + *((u_long *)(op+4)) = nextEntryCookie; + } - if (infoLevel <= 0x101) - *(origOp + ohbytes - 1) = (unsigned char) onbytes; - else if (infoLevel == 0x103) - *((u_long *)(op + 8)) = onbytes; - else - *((u_long *)(op + 60)) = onbytes; - strcpy(origOp+ohbytes, dep->name); - - /* Short name if requested and needed */ - if (infoLevel == 0x104) { - if (NeedShortName) { - strcpy(op + 70, shortName); - *(op + 68) = shortNameEnd - shortName; - } - } - - /* now, adjust the # of entries copied */ - returnedNames++; - - /* NextEntryOffset and FileIndex */ - if (infoLevel >= 101) { - int entryOffset = orbytes + align; - *((u_long *)op) = entryOffset; - *((u_long *)(op+4)) = nextEntryCookie; - } - - /* now we emit the attribute. This is tricky, since - * we need to really stat the file to find out what - * type of entry we've got. Right now, we're copying - * out data from * a buffer, while holding the scp - * locked, so it isn't really convenient to stat - * something now. We'll put in a place holder - * now, and make a second pass before returning this - * to get the real attributes. So, we just skip the - * data for now, and adjust it later. We allocate a - * patch record to make it easy to find this point - * later. The replay will happen at a time when it is - * safe to unlock the directory. - */ - if (infoLevel != 0x103) { - curPatchp = malloc(sizeof(*curPatchp)); - osi_QAdd((osi_queue_t **) &dirListPatchesp, - &curPatchp->q); - curPatchp->dptr = op; - if (infoLevel >= 0x101) - curPatchp->dptr += 8; - - if (smb_hideDotFiles && smb_IsDotFile(dep->name)) { - curPatchp->flags = SMB_DIRLISTPATCH_DOTFILE; - } - else - curPatchp->flags = 0; - - curPatchp->fid.cell = scp->fid.cell; - curPatchp->fid.volume = scp->fid.volume; - curPatchp->fid.vnode = ntohl(dep->fid.vnode); - curPatchp->fid.unique = ntohl(dep->fid.unique); - - /* temp */ - curPatchp->dep = dep; - } - - if (searchFlags & 4) - /* put out resume key */ - *((u_long *)origOp) = nextEntryCookie; - - /* Adjust byte ptr and count */ - origOp += orbytes; /* skip entire record */ - bytesInBuffer += orbytes; - - /* and pad the record out */ - while (--align >= 0) { - *origOp++ = 0; - bytesInBuffer++; - } - - } /* if we're including this name */ + /* now we emit the attribute. This is tricky, since + * we need to really stat the file to find out what + * type of entry we've got. Right now, we're copying + * out data from * a buffer, while holding the scp + * locked, so it isn't really convenient to stat + * something now. We'll put in a place holder + * now, and make a second pass before returning this + * to get the real attributes. So, we just skip the + * data for now, and adjust it later. We allocate a + * patch record to make it easy to find this point + * later. The replay will happen at a time when it is + * safe to unlock the directory. + */ + if (infoLevel != 0x103) { + curPatchp = malloc(sizeof(*curPatchp)); + osi_QAdd((osi_queue_t **) &dirListPatchesp, + &curPatchp->q); + curPatchp->dptr = op; + if (infoLevel >= 0x101) + curPatchp->dptr += 8; + + if (smb_hideDotFiles && smb_IsDotFile(dep->name)) { + curPatchp->flags = SMB_DIRLISTPATCH_DOTFILE; + } + else + curPatchp->flags = 0; + + curPatchp->fid.cell = scp->fid.cell; + curPatchp->fid.volume = scp->fid.volume; + curPatchp->fid.vnode = ntohl(dep->fid.vnode); + curPatchp->fid.unique = ntohl(dep->fid.unique); + + /* temp */ + curPatchp->dep = dep; + } + + if (searchFlags & 4) + /* put out resume key */ + *((u_long *)origOp) = nextEntryCookie; + /* Adjust byte ptr and count */ + origOp += orbytes; /* skip entire record */ + bytesInBuffer += orbytes; + + /* and pad the record out */ + while (--align >= 0) { + *origOp++ = 0; + bytesInBuffer++; + } + + } /* if we're including this name */ + nextEntry: - /* and adjust curOffset to be where the new cookie is */ - thyper.HighPart = 0; - thyper.LowPart = CM_DIR_CHUNKSIZE * numDirChunks; - curOffset = LargeIntegerAdd(thyper, curOffset); - } /* while copying data for dir listing */ + /* and adjust curOffset to be where the new cookie is */ + thyper.HighPart = 0; + thyper.LowPart = CM_DIR_CHUNKSIZE * numDirChunks; + curOffset = LargeIntegerAdd(thyper, curOffset); + } /* while copying data for dir listing */ /* release the mutex */ lock_ReleaseMutex(&scp->mx); - if (bufferp) buf_Release(bufferp); + if (bufferp) buf_Release(bufferp); /* apply and free last set of patches; if not doing a star match, this - * will be empty, but better safe (and freeing everything) than sorry. - */ - smb_ApplyV3DirListPatches(scp, &dirListPatchesp, infoLevel, userp, - &req); - - /* now put out the final parameters */ + * will be empty, but better safe (and freeing everything) than sorry. + */ + smb_ApplyV3DirListPatches(scp, &dirListPatchesp, infoLevel, userp, + &req); + + /* now put out the final parameters */ if (returnedNames == 0) eos = 1; - if (p->opcode == 1) { + if (p->opcode == 1) { /* find first */ - outp->parmsp[0] = (unsigned short) dsp->cookie; - outp->parmsp[1] = returnedNames; - outp->parmsp[2] = eos; - outp->parmsp[3] = 0; /* nothing wrong with EAS */ - outp->parmsp[4] = 0; /* don't need last name to continue - * search, cookie is enough. Normally, - * this is the offset of the file name - * of the last entry returned. - */ + outp->parmsp[0] = (unsigned short) dsp->cookie; + outp->parmsp[1] = returnedNames; + outp->parmsp[2] = eos; + outp->parmsp[3] = 0; /* nothing wrong with EAS */ + outp->parmsp[4] = 0; /* don't need last name to continue + * search, cookie is enough. Normally, + * this is the offset of the file name + * of the last entry returned. + */ outp->totalParms = 10; /* in bytes */ - } - else { + } + else { /* find next */ - outp->parmsp[0] = returnedNames; - outp->parmsp[1] = eos; - outp->parmsp[2] = 0; /* EAS error */ - outp->parmsp[3] = 0; /* last name, as above */ - outp->totalParms = 8; /* in bytes */ - } + outp->parmsp[0] = returnedNames; + outp->parmsp[1] = eos; + outp->parmsp[2] = 0; /* EAS error */ + outp->parmsp[3] = 0; /* last name, as above */ + outp->totalParms = 8; /* in bytes */ + } /* return # of bytes in the buffer */ - outp->totalData = bytesInBuffer; + outp->totalData = bytesInBuffer; osi_Log2(afsd_logp, "T2 search dir done, %d names, code %d", - returnedNames, code); + returnedNames, code); /* Return error code if unsuccessful on first request */ if (code == 0 && p->opcode == 1 && returnedNames == 0) code = CM_ERROR_NOSUCHFILE; /* if we're supposed to close the search after this request, or if - * we're supposed to close the search if we're done, and we're done, - * or if something went wrong, close the search. - */ - /* ((searchFlags & 1) || ((searchFlags & 2) && eos) */ - /* pbh - added patch submitted to openafs-dev from James Petterson on 26 Feb, 2003 */ - if ((searchFlags & 1) || (returnedNames == 0) || ((searchFlags & 2) && eos) - || code != 0) - smb_DeleteDirSearch(dsp); + * we're supposed to close the search if we're done, and we're done, + * or if something went wrong, close the search. + */ + /* ((searchFlags & 1) || ((searchFlags & 2) && eos) */ + if ((searchFlags & 1) || (returnedNames == 0) || ((searchFlags & 2) && + eos) || code != 0) + smb_DeleteDirSearch(dsp); if (code) - smb_SendTran2Error(vcp, p, opx, code); + smb_SendTran2Error(vcp, p, opx, code); else { - smb_SendTran2Packet(vcp, outp, opx); + smb_SendTran2Packet(vcp, outp, opx); } smb_FreeTran2Packet(outp); - smb_ReleaseDirSearch(dsp); - cm_ReleaseSCache(scp); - cm_ReleaseUser(userp); - return 0; + smb_ReleaseDirSearch(dsp); + cm_ReleaseSCache(scp); + cm_ReleaseUser(userp); + return 0; } long smb_ReceiveV3FindClose(smb_vc_t *vcp, smb_packet_t *inp, smb_packet_t *outp) { - int dirHandle; - smb_dirSearch_t *dsp; + int dirHandle; + smb_dirSearch_t *dsp; - dirHandle = smb_GetSMBParm(inp, 0); + dirHandle = smb_GetSMBParm(inp, 0); - osi_Log1(afsd_logp, "SMB3 find close handle %d", dirHandle); + osi_Log1(afsd_logp, "SMB3 find close handle %d", dirHandle); - dsp = smb_FindDirSearch(dirHandle); + dsp = smb_FindDirSearch(dirHandle); - if (!dsp) + if (!dsp) return CM_ERROR_BADFD; - /* otherwise, we have an FD to destroy */ - smb_DeleteDirSearch(dsp); - smb_ReleaseDirSearch(dsp); + /* otherwise, we have an FD to destroy */ + smb_DeleteDirSearch(dsp); + smb_ReleaseDirSearch(dsp); /* and return results */ smb_SetSMBDataLength(outp, 0); - return 0; + return 0; } long smb_ReceiveV3FindNotifyClose(smb_vc_t *vcp, smb_packet_t *inp, smb_packet_t *outp) { smb_SetSMBDataLength(outp, 0); - return 0; + return 0; } long smb_ReceiveV3OpenX(smb_vc_t *vcp, smb_packet_t *inp, smb_packet_t *outp) { char *pathp; - long code; + long code; cm_space_t *spacep; - int excl; - cm_user_t *userp; - cm_scache_t *dscp; /* dir we're dealing with */ - cm_scache_t *scp; /* file we're creating */ - cm_attr_t setAttr; - int initialModeBits; - smb_fid_t *fidp; - int attributes; - char *lastNamep; - long dosTime; - int openFun; - int trunc; - int openMode; - int extraInfo; - int openAction; - int parmSlot; /* which parm we're dealing with */ + int excl; + cm_user_t *userp; + cm_scache_t *dscp; /* dir we're dealing with */ + cm_scache_t *scp; /* file we're creating */ + cm_attr_t setAttr; + int initialModeBits; + smb_fid_t *fidp; + int attributes; + char *lastNamep; + long dosTime; + int openFun; + int trunc; + int openMode; + int extraInfo; + int openAction; + int parmSlot; /* which parm we're dealing with */ char *tidPathp; cm_req_t req; cm_InitReq(&req); - scp = NULL; + scp = NULL; 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 */ + excl = ((openFun & 3) == 0); + 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); - 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 */ - initialModeBits = 0666; - if (attributes & 1) initialModeBits &= ~0222; + initialModeBits = 0666; + if (attributes & 1) initialModeBits &= ~0222; - pathp = smb_GetSMBData(inp, NULL); + pathp = smb_GetSMBData(inp, NULL); spacep = inp->spacep; - smb_StripLastComponent(spacep->data, &lastNamep, pathp); + smb_StripLastComponent(spacep->data, &lastNamep, pathp); if (lastNamep && strcmp(lastNamep, SMB_IOCTL_FILENAME) == 0) { /* special case magic file name for receiving IOCTL requests - * (since IOCTL calls themselves aren't getting through). - */ + * (since IOCTL calls themselves aren't getting through). + */ #ifdef NOTSERVICE - osi_Log0(afsd_logp, "IOCTL Open"); + osi_Log0(afsd_logp, "IOCTL Open"); #endif - fidp = smb_FindFID(vcp, 0, SMB_FLAG_CREATE); - smb_SetupIoctlFid(fidp, spacep); + + fidp = smb_FindFID(vcp, 0, SMB_FLAG_CREATE); + smb_SetupIoctlFid(fidp, spacep); /* set inp->fid so that later read calls in same msg can find fid */ - inp->fid = fidp->fid; + inp->fid = fidp->fid; - /* copy out remainder of the parms */ + /* copy out remainder of the parms */ parmSlot = 2; smb_SetSMBParm(outp, parmSlot, fidp->fid); parmSlot++; if (extraInfo) { - smb_SetSMBParm(outp, parmSlot, /* attrs */ 0); parmSlot++; - smb_SetSMBParm(outp, parmSlot, 0); parmSlot++; /* mod time */ - smb_SetSMBParm(outp, parmSlot, 0); parmSlot++; - smb_SetSMBParm(outp, parmSlot, 0); parmSlot++; /* len */ - smb_SetSMBParm(outp, parmSlot, 0x7fff); parmSlot++; - smb_SetSMBParm(outp, parmSlot, openMode); parmSlot++; - smb_SetSMBParm(outp, parmSlot, 0); parmSlot++; /* file type 0 ==> normal file or dir */ - smb_SetSMBParm(outp, parmSlot, 0); parmSlot++; /* IPC junk */ - } + smb_SetSMBParm(outp, parmSlot, /* attrs */ 0); parmSlot++; + smb_SetSMBParm(outp, parmSlot, 0); parmSlot++; /* mod time */ + smb_SetSMBParm(outp, parmSlot, 0); parmSlot++; + smb_SetSMBParm(outp, parmSlot, 0); parmSlot++; /* len */ + smb_SetSMBParm(outp, parmSlot, 0x7fff); parmSlot++; + smb_SetSMBParm(outp, parmSlot, openMode); parmSlot++; + smb_SetSMBParm(outp, parmSlot, 0); parmSlot++; /* file type 0 ==> normal file or dir */ + smb_SetSMBParm(outp, parmSlot, 0); parmSlot++; /* IPC junk */ + } /* and the final "always present" stuff */ - smb_SetSMBParm(outp, parmSlot, /* openAction found existing file */ 1); parmSlot++; + smb_SetSMBParm(outp, parmSlot, /* openAction found existing file */ 1); parmSlot++; /* next write out the "unique" ID */ smb_SetSMBParm(outp, parmSlot, 0x1234); parmSlot++; smb_SetSMBParm(outp, parmSlot, 0x5678); parmSlot++; - smb_SetSMBParm(outp, parmSlot, 0); parmSlot++; - smb_SetSMBDataLength(outp, 0); + smb_SetSMBParm(outp, parmSlot, 0); parmSlot++; + smb_SetSMBDataLength(outp, 0); /* and clean up fid reference */ - smb_ReleaseFID(fidp); - return 0; - } + smb_ReleaseFID(fidp); + return 0; + } #ifdef DEBUG_VERBOSE - { - char *hexp, *asciip; - asciip = (lastNamep ? lastNamep : pathp ); - hexp = osi_HexifyString(asciip); - DEBUG_EVENT2("AFS", "V3Open H[%s] A[%s]", hexp, asciip ); - free(hexp); - } + { + char *hexp, *asciip; + asciip = (lastNamep ? lastNamep : pathp ); + hexp = osi_HexifyString(asciip); + DEBUG_EVENT2("AFS", "V3Open H[%s] A[%s]", hexp, asciip ); + free(hexp); + } #endif - - userp = smb_GetUser(vcp, inp); + userp = smb_GetUser(vcp, inp); dscp = NULL; tidPathp = smb_GetTIDPath(vcp, ((smb_t *)inp)->tid); code = cm_NameI(cm_rootSCachep, pathp, - CM_FLAG_FOLLOW | CM_FLAG_CASEFOLD, - userp, tidPathp, &req, &scp); + CM_FLAG_FOLLOW | CM_FLAG_CASEFOLD, + userp, tidPathp, &req, &scp); if (code != 0) { code = cm_NameI(cm_rootSCachep, spacep->data, - CM_FLAG_FOLLOW | CM_FLAG_CASEFOLD, - userp, tidPathp, &req, &dscp); + CM_FLAG_FOLLOW | CM_FLAG_CASEFOLD, + userp, tidPathp, &req, &dscp); - if (code) { - cm_ReleaseUser(userp); - return code; - } + if (code) { + cm_ReleaseUser(userp); + return code; + } - /* otherwise, scp points to the parent directory. Do a lookup, - * and truncate the file if we find it, otherwise we create the - * file. - */ - if (!lastNamep) lastNamep = pathp; - else lastNamep++; - code = cm_Lookup(dscp, lastNamep, CM_FLAG_CASEFOLD, userp, - &req, &scp); - if (code && code != CM_ERROR_NOSUCHFILE) { + /* otherwise, scp points to the parent directory. Do a lookup, + * and truncate the file if we find it, otherwise we create the + * file. + */ + if (!lastNamep) lastNamep = pathp; + else lastNamep++; + code = cm_Lookup(dscp, lastNamep, CM_FLAG_CASEFOLD, userp, + &req, &scp); + if (code && code != CM_ERROR_NOSUCHFILE) { cm_ReleaseSCache(dscp); - cm_ReleaseUser(userp); - return code; - } + cm_ReleaseUser(userp); + return code; + } } - /* 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 - * by dscp, or we may have found the file directly. If code is non-zero, - * scp is NULL. - */ + /* 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 + * by dscp, or we may have found the file directly. If code is non-zero, + * scp is NULL. + */ if (code == 0) { - code = cm_CheckOpen(scp, openMode, trunc, userp, &req); - if (code) { - if (dscp) cm_ReleaseSCache(dscp); - cm_ReleaseSCache(scp); - cm_ReleaseUser(userp); - return code; - } + code = cm_CheckOpen(scp, openMode, trunc, userp, &req); + if (code) { + if (dscp) cm_ReleaseSCache(dscp); + cm_ReleaseSCache(scp); + cm_ReleaseUser(userp); + return code; + } if (excl) { /* oops, file shouldn't be there */ - if (dscp) cm_ReleaseSCache(dscp); - cm_ReleaseSCache(scp); - cm_ReleaseUser(userp); - return CM_ERROR_EXISTS; - } + if (dscp) cm_ReleaseSCache(dscp); + cm_ReleaseSCache(scp); + cm_ReleaseUser(userp); + return CM_ERROR_EXISTS; + } if (trunc) { setAttr.mask = CM_ATTRMASK_LENGTH; - setAttr.length.LowPart = 0; - setAttr.length.HighPart = 0; + setAttr.length.LowPart = 0; + setAttr.length.HighPart = 0; code = cm_SetAttr(scp, &setAttr, userp, &req); - openAction = 3; /* truncated existing file */ + openAction = 3; /* truncated existing file */ } - else openAction = 1; /* found existing file */ - } + else openAction = 1; /* found existing file */ + } else if (!(openFun & 0x10)) { /* don't create if not found */ - if (dscp) cm_ReleaseSCache(dscp); - cm_ReleaseUser(userp); - return CM_ERROR_NOSUCHFILE; - } - else { + if (dscp) cm_ReleaseSCache(dscp); + cm_ReleaseUser(userp); + return CM_ERROR_NOSUCHFILE; + } + else { osi_assert(dscp != NULL); osi_Log1(afsd_logp, "smb_ReceiveV3OpenX creating file %s", - osi_LogSaveString(afsd_logp, lastNamep)); + osi_LogSaveString(afsd_logp, lastNamep)); openAction = 2; /* created file */ setAttr.mask = CM_ATTRMASK_CLIENTMODTIME; smb_UnixTimeFromDosUTime(&setAttr.clientModTime, dosTime); - code = cm_Create(dscp, lastNamep, 0, &setAttr, &scp, userp, - &req); + 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) { + FILE_NOTIFY_CHANGE_FILE_NAME, + dscp, lastNamep, NULL, TRUE); + 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 * fails, that means that the file was deleted after we * started this call. - */ - code = cm_Lookup(dscp, lastNamep, CM_FLAG_CASEFOLD, - userp, &req, &scp); - if (code == 0) { - if (trunc) { + */ + code = cm_Lookup(dscp, lastNamep, CM_FLAG_CASEFOLD, + userp, &req, &scp); + if (code == 0) { + if (trunc) { setAttr.mask = CM_ATTRMASK_LENGTH; - setAttr.length.LowPart = 0; - setAttr.length.HighPart = 0; - code = cm_SetAttr(scp, &setAttr, userp, - &req); - } + setAttr.length.LowPart = 0; + setAttr.length.HighPart = 0; + code = cm_SetAttr(scp, &setAttr, userp, &req); + } } /* lookup succeeded */ - } } + } /* we don't need this any longer */ if (dscp) cm_ReleaseSCache(dscp); - if (code) { + if (code) { /* something went wrong creating or truncating the file */ - if (scp) cm_ReleaseSCache(scp); - cm_ReleaseUser(userp); - return code; - } + if (scp) cm_ReleaseSCache(scp); + cm_ReleaseUser(userp); + return code; + } /* make sure we're about to open a file */ if (scp->fileType != CM_SCACHETYPE_FILE) { @@ -2708,55 +2702,55 @@ long smb_ReceiveV3OpenX(smb_vc_t *vcp, smb_packet_t *inp, smb_packet_t *outp) return CM_ERROR_ISDIR; } - /* now all we have to do is open the file itself */ - fidp = smb_FindFID(vcp, 0, SMB_FLAG_CREATE); - osi_assert(fidp); + /* now all we have to do is open the file itself */ + fidp = smb_FindFID(vcp, 0, SMB_FLAG_CREATE); + osi_assert(fidp); /* save a pointer to the vnode */ - fidp->scp = scp; + fidp->scp = scp; /* compute open mode */ - if (openMode != 1) fidp->flags |= SMB_FID_OPENREAD; - if (openMode == 1 || openMode == 2) - fidp->flags |= SMB_FID_OPENWRITE; + if (openMode != 1) fidp->flags |= SMB_FID_OPENREAD; + if (openMode == 1 || openMode == 2) + fidp->flags |= SMB_FID_OPENWRITE; smb_ReleaseFID(fidp); cm_Open(scp, 0, userp); /* set inp->fid so that later read calls in same msg can find fid */ - inp->fid = fidp->fid; + inp->fid = fidp->fid; - /* copy out remainder of the parms */ + /* copy out remainder of the parms */ parmSlot = 2; smb_SetSMBParm(outp, parmSlot, fidp->fid); parmSlot++; lock_ObtainMutex(&scp->mx); if (extraInfo) { - smb_SetSMBParm(outp, parmSlot, smb_Attributes(scp)); parmSlot++; + smb_SetSMBParm(outp, parmSlot, smb_Attributes(scp)); parmSlot++; smb_DosUTimeFromUnixTime(&dosTime, scp->clientModTime); - smb_SetSMBParm(outp, parmSlot, dosTime & 0xffff); parmSlot++; - smb_SetSMBParm(outp, parmSlot, (dosTime>>16) & 0xffff); parmSlot++; - smb_SetSMBParm(outp, parmSlot, scp->length.LowPart & 0xffff); parmSlot++; - smb_SetSMBParm(outp, parmSlot, (scp->length.LowPart >> 16) & 0xffff); parmSlot++; - smb_SetSMBParm(outp, parmSlot, openMode); parmSlot++; - smb_SetSMBParm(outp, parmSlot, 0); parmSlot++; /* file type 0 ==> normal file or dir */ - smb_SetSMBParm(outp, parmSlot, 0); parmSlot++; /* IPC junk */ + smb_SetSMBParm(outp, parmSlot, dosTime & 0xffff); parmSlot++; + smb_SetSMBParm(outp, parmSlot, (dosTime>>16) & 0xffff); parmSlot++; + smb_SetSMBParm(outp, parmSlot, scp->length.LowPart & 0xffff); parmSlot++; + smb_SetSMBParm(outp, parmSlot, (scp->length.LowPart >> 16) & 0xffff); parmSlot++; + smb_SetSMBParm(outp, parmSlot, openMode); parmSlot++; + smb_SetSMBParm(outp, parmSlot, 0); parmSlot++; /* file type 0 ==> normal file or dir */ + smb_SetSMBParm(outp, parmSlot, 0); parmSlot++; /* IPC junk */ } /* and the final "always present" stuff */ - smb_SetSMBParm(outp, parmSlot, openAction); parmSlot++; + smb_SetSMBParm(outp, parmSlot, openAction); parmSlot++; /* next write out the "unique" ID */ smb_SetSMBParm(outp, parmSlot, scp->fid.vnode & 0xffff); parmSlot++; smb_SetSMBParm(outp, parmSlot, scp->fid.volume & 0xffff); parmSlot++; - smb_SetSMBParm(outp, parmSlot, 0); parmSlot++; + smb_SetSMBParm(outp, parmSlot, 0); parmSlot++; lock_ReleaseMutex(&scp->mx); - smb_SetSMBDataLength(outp, 0); + smb_SetSMBDataLength(outp, 0); osi_Log1(afsd_logp, "SMB OpenX opening fid %d", fidp->fid); - cm_ReleaseUser(userp); - /* leave scp held since we put it in fidp->scp */ - return 0; -} + cm_ReleaseUser(userp); + /* leave scp held since we put it in fidp->scp */ + return 0; +} long smb_ReceiveV3LockingX(smb_vc_t *vcp, smb_packet_t *inp, smb_packet_t *outp) { @@ -2785,7 +2779,7 @@ long smb_ReceiveV3LockingX(smb_vc_t *vcp, smb_packet_t *inp, smb_packet_t *outp) return CM_ERROR_BADFD; } /* set inp->fid so that later read calls in same msg can find fid */ - inp->fid = fid; + inp->fid = fid; userp = smb_GetUser(vcp, inp); @@ -2891,57 +2885,57 @@ doneSync: long smb_ReceiveV3GetAttributes(smb_vc_t *vcp, smb_packet_t *inp, smb_packet_t *outp) { unsigned short fid; - smb_fid_t *fidp; - cm_scache_t *scp; - long code; - long searchTime; - cm_user_t *userp; + smb_fid_t *fidp; + cm_scache_t *scp; + long code; + long searchTime; + cm_user_t *userp; cm_req_t req; cm_InitReq(&req); - fid = smb_GetSMBParm(inp, 0); - fid = smb_ChainFID(fid, inp); + fid = smb_GetSMBParm(inp, 0); + fid = smb_ChainFID(fid, inp); - fidp = smb_FindFID(vcp, fid, 0); - if (!fidp || (fidp->flags & SMB_FID_IOCTL)) { + fidp = smb_FindFID(vcp, fid, 0); + if (!fidp || (fidp->flags & SMB_FID_IOCTL)) { return CM_ERROR_BADFD; - } + } - userp = smb_GetUser(vcp, inp); + userp = smb_GetUser(vcp, inp); - scp = fidp->scp; + scp = fidp->scp; - /* otherwise, stat the file */ + /* otherwise, stat the file */ lock_ObtainMutex(&scp->mx); - code = cm_SyncOp(scp, NULL, userp, &req, 0, - CM_SCACHESYNC_NEEDCALLBACK | CM_SCACHESYNC_GETSTATUS); + code = cm_SyncOp(scp, NULL, userp, &req, 0, + CM_SCACHESYNC_NEEDCALLBACK | CM_SCACHESYNC_GETSTATUS); 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 - * searchTime variable. So we take the high-order bits first. - */ + * call provides the date first, not the time, as returned in the + * searchTime variable. So we take the high-order bits first. + */ smb_SearchTimeFromUnixTime(&searchTime, scp->clientModTime); - smb_SetSMBParm(outp, 0, (searchTime >> 16) & 0xffff); /* ctime */ - smb_SetSMBParm(outp, 1, searchTime & 0xffff); - smb_SetSMBParm(outp, 2, (searchTime >> 16) & 0xffff); /* atime */ - smb_SetSMBParm(outp, 3, searchTime & 0xffff); - smb_SetSMBParm(outp, 4, (searchTime >> 16) & 0xffff); /* mtime */ - smb_SetSMBParm(outp, 5, searchTime & 0xffff); - - /* now handle file size and allocation size */ - smb_SetSMBParm(outp, 6, scp->length.LowPart & 0xffff); /* file size */ - smb_SetSMBParm(outp, 7, (scp->length.LowPart >> 16) & 0xffff); - smb_SetSMBParm(outp, 8, scp->length.LowPart & 0xffff); /* alloc size */ - smb_SetSMBParm(outp, 9, (scp->length.LowPart >> 16) & 0xffff); - + smb_SetSMBParm(outp, 0, (searchTime >> 16) & 0xffff); /* ctime */ + smb_SetSMBParm(outp, 1, searchTime & 0xffff); + smb_SetSMBParm(outp, 2, (searchTime >> 16) & 0xffff); /* atime */ + smb_SetSMBParm(outp, 3, searchTime & 0xffff); + smb_SetSMBParm(outp, 4, (searchTime >> 16) & 0xffff); /* mtime */ + smb_SetSMBParm(outp, 5, searchTime & 0xffff); + + /* now handle file size and allocation size */ + smb_SetSMBParm(outp, 6, scp->length.LowPart & 0xffff); /* file size */ + smb_SetSMBParm(outp, 7, (scp->length.LowPart >> 16) & 0xffff); + smb_SetSMBParm(outp, 8, scp->length.LowPart & 0xffff); /* alloc size */ + smb_SetSMBParm(outp, 9, (scp->length.LowPart >> 16) & 0xffff); + /* file attribute */ - smb_SetSMBParm(outp, 10, smb_Attributes(scp)); + smb_SetSMBParm(outp, 10, smb_Attributes(scp)); - /* and finalize stuff */ - smb_SetSMBDataLength(outp, 0); - code = 0; + /* and finalize stuff */ + smb_SetSMBDataLength(outp, 0); + code = 0; done: lock_ReleaseMutex(&scp->mx); @@ -2953,51 +2947,49 @@ done: long smb_ReceiveV3SetAttributes(smb_vc_t *vcp, smb_packet_t *inp, smb_packet_t *outp) { unsigned short fid; - smb_fid_t *fidp; - cm_scache_t *scp; - long code; + smb_fid_t *fidp; + cm_scache_t *scp; + long code; long searchTime; - long unixTime; - cm_user_t *userp; - cm_attr_t attrs; + long unixTime; + cm_user_t *userp; + cm_attr_t attrs; cm_req_t req; cm_InitReq(&req); - fid = smb_GetSMBParm(inp, 0); - fid = smb_ChainFID(fid, inp); + fid = smb_GetSMBParm(inp, 0); + fid = smb_ChainFID(fid, inp); - fidp = smb_FindFID(vcp, fid, 0); - if (!fidp || (fidp->flags & SMB_FID_IOCTL)) { + fidp = smb_FindFID(vcp, fid, 0); + if (!fidp || (fidp->flags & SMB_FID_IOCTL)) { return CM_ERROR_BADFD; - } + } - userp = smb_GetUser(vcp, inp); + userp = smb_GetUser(vcp, inp); - scp = fidp->scp; + 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 - * requested. The others we'll ignore. - */ + * and AFS only implements mtime, and we'll set the mtime if that's + * requested. The others we'll ignore. + */ searchTime = smb_GetSMBParm(inp, 5) | (smb_GetSMBParm(inp, 6) << 16); - if (searchTime != 0) { + if (searchTime != 0) { smb_UnixTimeFromSearchTime(&unixTime, searchTime); - if (unixTime != -1) { - attrs.mask = CM_ATTRMASK_CLIENTMODTIME; - attrs.clientModTime = unixTime; - code = cm_SetAttr(scp, &attrs, userp, &req); + if ( unixTime != -1 ) { + attrs.mask = CM_ATTRMASK_CLIENTMODTIME; + attrs.clientModTime = unixTime; + code = cm_SetAttr(scp, &attrs, userp, &req); - osi_Log1(afsd_logp, "SMB receive V3SetAttributes [fid=%ld]", fid); - } - else { - osi_Log1(afsd_logp, "**smb_UnixTimeFromSearchTime failed searchTime=%ld", searchTime); - } - - } - else code = 0; + osi_Log1(afsd_logp, "SMB receive V3SetAttributes [fid=%ld]", fid); + } else { + osi_Log1(afsd_logp, "**smb_UnixTimeFromSearchTime failed searchTime=%ld", searchTime); + } + } + else code = 0; cm_ReleaseUser(userp); smb_ReleaseFID(fidp); @@ -3008,59 +3000,59 @@ long smb_ReceiveV3SetAttributes(smb_vc_t *vcp, smb_packet_t *inp, smb_packet_t * long smb_ReceiveV3ReadX(smb_vc_t *vcp, smb_packet_t *inp, smb_packet_t *outp) { osi_hyper_t offset; - long count, finalCount; - unsigned short fd; - smb_fid_t *fidp; - long code; - cm_user_t *userp; - char *op; - - 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); + long count, finalCount; + unsigned short fd; + smb_fid_t *fidp; + long code; + cm_user_t *userp; + char *op; - osi_Log3(afsd_logp, "smb_ReceiveV3Read fd %d, off 0x%x, size 0x%x", - fd, offset.LowPart, count); + 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(afsd_logp, "smb_ReceiveV3Read fd %d, off 0x%x, size 0x%x", + fd, offset.LowPart, count); fd = smb_ChainFID(fd, inp); - fidp = smb_FindFID(vcp, fd, 0); - if (!fidp) { + fidp = smb_FindFID(vcp, fd, 0); + if (!fidp) { return CM_ERROR_BADFD; - } + } /* set inp->fid so that later read calls in same msg can find fid */ - inp->fid = fd; + inp->fid = fd; - if (fidp->flags & SMB_FID_IOCTL) { + 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, - * and will be further filled in after we return. - */ - smb_SetSMBParm(outp, 2, 0); /* remaining bytes, for pipes */ - smb_SetSMBParm(outp, 3, 0); /* resvd */ - smb_SetSMBParm(outp, 4, 0); /* resvd */ + * and will be further filled in after we return. + */ + smb_SetSMBParm(outp, 2, 0); /* remaining bytes, for pipes */ + smb_SetSMBParm(outp, 3, 0); /* resvd */ + smb_SetSMBParm(outp, 4, 0); /* resvd */ smb_SetSMBParm(outp, 5, count); /* # of bytes we're going to read */ - /* fill in #6 when we have all the parameters' space reserved */ - smb_SetSMBParm(outp, 7, 0); /* resv'd */ - smb_SetSMBParm(outp, 8, 0); /* resv'd */ - smb_SetSMBParm(outp, 9, 0); /* resv'd */ - smb_SetSMBParm(outp, 10, 0); /* resv'd */ + /* fill in #6 when we have all the parameters' space reserved */ + smb_SetSMBParm(outp, 7, 0); /* resv'd */ + smb_SetSMBParm(outp, 8, 0); /* resv'd */ + smb_SetSMBParm(outp, 9, 0); /* resv'd */ + smb_SetSMBParm(outp, 10, 0); /* resv'd */ smb_SetSMBParm(outp, 11, 0); /* reserved */ /* get op ptr after putting in the parms, since otherwise we don't - * know where the data really is. - */ - op = smb_GetSMBData(outp, NULL); + * know where the data really is. + */ + op = smb_GetSMBData(outp, NULL); - /* now fill in offset from start of SMB header to first data byte (to op) */ - smb_SetSMBParm(outp, 6, ((int) (op - outp->data))); + /* now fill in offset from start of SMB header to first data byte (to op) */ + smb_SetSMBParm(outp, 6, ((int) (op - outp->data))); /* set the packet data length the count of the # of bytes */ - smb_SetSMBDataLength(outp, count); + smb_SetSMBDataLength(outp, count); #ifndef DJGPP code = smb_ReadData(fidp, &offset, count, op, userp, &finalCount); @@ -3072,11 +3064,11 @@ long smb_ReceiveV3ReadX(smb_vc_t *vcp, smb_packet_t *inp, smb_packet_t *outp) smb_SetSMBParm(outp, 5, finalCount); smb_SetSMBDataLength(outp, finalCount); - smb_ReleaseFID(fidp); + smb_ReleaseFID(fidp); - cm_ReleaseUser(userp); - return code; -} + cm_ReleaseUser(userp); + return code; +} /* * Values for createDisp, copied from NTDDK.H @@ -3099,13 +3091,13 @@ long smb_ReceiveNTCreateX(smb_vc_t *vcp, smb_packet_t *inp, smb_packet_t *outp) cm_scache_t *scp; /* file to create or open */ cm_attr_t setAttr; char *lastNamep; - char *treeStartp; + char *treeStartp; unsigned short nameLength; unsigned int flags; unsigned int requestOpLock; unsigned int requestBatchOpLock; unsigned int mustBeDir; - unsigned int treeCreate; + unsigned int treeCreate; int realDirFlag; unsigned int desiredAccess; unsigned int extAttributes; @@ -3127,36 +3119,36 @@ long smb_ReceiveNTCreateX(smb_vc_t *vcp, smb_packet_t *inp, smb_packet_t *outp) cm_InitReq(&req); - treeCreate = FALSE; + treeCreate = FALSE; foundscp = FALSE; scp = NULL; nameLength = smb_GetSMBOffsetParm(inp, 2, 1); flags = smb_GetSMBOffsetParm(inp, 3, 1) - | (smb_GetSMBOffsetParm(inp, 4, 1) << 16); + | (smb_GetSMBOffsetParm(inp, 4, 1) << 16); requestOpLock = flags & 0x02; requestBatchOpLock = flags & 0x04; mustBeDir = flags & 0x08; /* - * Why all of a sudden 32-bit FID? - * We will reject all bits higher than 16. - */ + * Why all of a sudden 32-bit FID? + * We will reject all bits higher than 16. + */ if (smb_GetSMBOffsetParm(inp, 6, 1) != 0) return CM_ERROR_INVAL; baseFid = smb_GetSMBOffsetParm(inp, 5, 1); desiredAccess = smb_GetSMBOffsetParm(inp, 7, 1) - | (smb_GetSMBOffsetParm(inp, 8, 1) << 16); + | (smb_GetSMBOffsetParm(inp, 8, 1) << 16); extAttributes = smb_GetSMBOffsetParm(inp, 13, 1) - | (smb_GetSMBOffsetParm(inp, 14, 1) << 16); + | (smb_GetSMBOffsetParm(inp, 14, 1) << 16); createDisp = smb_GetSMBOffsetParm(inp, 17, 1) - | (smb_GetSMBOffsetParm(inp, 18, 1) << 16); + | (smb_GetSMBOffsetParm(inp, 18, 1) << 16); createOptions = smb_GetSMBOffsetParm(inp, 19, 1) - | (smb_GetSMBOffsetParm(inp, 20, 1) << 16); + | (smb_GetSMBOffsetParm(inp, 20, 1) << 16); /* mustBeDir is never set; createOptions directory bit seems to be - * more important - */ + * more important + */ if (createOptions & 1) realDirFlag = 1; else if (createOptions & 0x40) @@ -3165,9 +3157,9 @@ long smb_ReceiveNTCreateX(smb_vc_t *vcp, smb_packet_t *inp, smb_packet_t *outp) realDirFlag = -1; /* - * compute initial mode bits based on read-only flag in - * extended attributes - */ + * compute initial mode bits based on read-only flag in + * extended attributes + */ initialModeBits = 0666; if (extAttributes & 1) initialModeBits &= ~0222; @@ -3180,13 +3172,13 @@ long smb_ReceiveNTCreateX(smb_vc_t *vcp, smb_packet_t *inp, smb_packet_t *outp) spacep = inp->spacep; smb_StripLastComponent(spacep->data, &lastNamep, realPathp); - osi_Log1(afsd_logp,"NTCreateX for [%s]",osi_LogSaveString(afsd_logp,realPathp)); - osi_Log4(afsd_logp,"NTCreateX da=[%x] ea=[%x] cd=[%x] co=[%x]", desiredAccess, extAttributes, createDisp, createOptions); + osi_Log1(afsd_logp,"NTCreateX for [%s]",osi_LogSaveString(afsd_logp,realPathp)); + osi_Log4(afsd_logp,"NTCreateX da=[%x] ea=[%x] cd=[%x] co=[%x]", desiredAccess, extAttributes, createDisp, createOptions); if (lastNamep && strcmp(lastNamep, SMB_IOCTL_FILENAME) == 0) { /* special case magic file name for receiving IOCTL requests - * (since IOCTL calls themselves aren't getting through). - */ + * (since IOCTL calls themselves aren't getting through). + */ fidp = smb_FindFID(vcp, 0, SMB_FLAG_CREATE); smb_SetupIoctlFid(fidp, spacep); @@ -3220,42 +3212,40 @@ long smb_ReceiveNTCreateX(smb_vc_t *vcp, smb_packet_t *inp, smb_packet_t *outp) } #ifdef DEBUG_VERBOSE - { - char *hexp, *asciip; - asciip = (lastNamep? lastNamep : realPathp); - hexp = osi_HexifyString( asciip ); - DEBUG_EVENT2("AFS", "NTCreateX H[%s] A[%s]", hexp, asciip); - free(hexp); - } + { + char *hexp, *asciip; + asciip = (lastNamep? lastNamep : realPathp); + hexp = osi_HexifyString( asciip ); + DEBUG_EVENT2("AFS", "NTCreateX H[%s] A[%s]", hexp, asciip); + free(hexp); + } #endif - - userp = smb_GetUser(vcp, inp); - - if(!userp) { - osi_Log1(afsd_logp, "NTCreateX Invalid user [%d]", ((smb_t *) inp)->uid); - free(realPathp); - return CM_ERROR_INVAL; - } + userp = smb_GetUser(vcp, inp); + if (!userp) { + osi_Log1(afsd_logp, "NTCreateX Invalid user [%d]", ((smb_t *) inp)->uid); + free(realPathp); + return CM_ERROR_INVAL; + } if (baseFid == 0) { baseDirp = cm_rootSCachep; tidPathp = smb_GetTIDPath(vcp, ((smb_t *)inp)->tid); } else { - baseFidp = smb_FindFID(vcp, baseFid, 0); - if(!baseFidp) { - osi_Log1(afsd_logp, "NTCreateX Invalid base fid [%d]", baseFid); - free(realPathp); - cm_ReleaseUser(userp); - return CM_ERROR_INVAL; - } + baseFidp = smb_FindFID(vcp, baseFid, 0); + if (!baseFidp) { + osi_Log1(afsd_logp, "NTCreateX Invalid base fid [%d]", baseFid); + free(realPathp); + cm_ReleaseUser(userp); + return CM_ERROR_INVAL; + } baseDirp = baseFidp->scp; tidPathp = NULL; } - osi_Log1(afsd_logp, "NTCreateX tidPathp=[%s]", (tidPathp==NULL)?"null": osi_LogSaveString(afsd_logp,tidPathp)); - - /* compute open mode */ + osi_Log1(afsd_logp, "NTCreateX tidPathp=[%s]", (tidPathp==NULL)?"null": osi_LogSaveString(afsd_logp,tidPathp)); + + /* compute open mode */ fidflags = 0; if (desiredAccess & DELETE) fidflags |= SMB_FID_OPENDELETE; @@ -3267,93 +3257,93 @@ long smb_ReceiveNTCreateX(smb_vc_t *vcp, smb_packet_t *inp, smb_packet_t *outp) dscp = NULL; code = 0; code = cm_NameI(baseDirp, realPathp, CM_FLAG_FOLLOW | CM_FLAG_CASEFOLD, - userp, tidPathp, &req, &scp); + userp, tidPathp, &req, &scp); if (code == 0) foundscp = TRUE; if (code != 0 - || (fidflags & (SMB_FID_OPENDELETE | SMB_FID_OPENWRITE))) { - /* look up parent directory */ - /* If we are trying to create a path (i.e. multiple nested directories), then we don't *need* - the immediate parent. We have to work our way up realPathp until we hit something that we - recognize. - */ - - while(1) { - char *tp; - - code = cm_NameI(baseDirp, spacep->data, - CM_FLAG_FOLLOW | CM_FLAG_CASEFOLD, - userp, tidPathp, &req, &dscp); - - if(code && - (tp = strrchr(spacep->data,'\\')) && - (createDisp == 2) && - (realDirFlag == 1)) { - *tp++ = 0; - treeCreate = TRUE; - treeStartp = realPathp + (tp - spacep->data); - - if(*tp && !smb_IsLegalFilename(tp)) { - if(baseFid != 0) smb_ReleaseFID(baseFidp); - cm_ReleaseUser(userp); - free(realPathp); - return CM_ERROR_BADNTFILENAME; - } - } - else - break; - } + || (fidflags & (SMB_FID_OPENDELETE | SMB_FID_OPENWRITE))) { + /* look up parent directory */ + /* If we are trying to create a path (i.e. multiple nested directories), then we don't *need* + the immediate parent. We have to work our way up realPathp until we hit something that we + recognize. + */ + + while(1) { + char *tp; + + code = cm_NameI(baseDirp, spacep->data, + CM_FLAG_FOLLOW | CM_FLAG_CASEFOLD, + userp, tidPathp, &req, &dscp); + + if (code && + (tp = strrchr(spacep->data,'\\')) && + (createDisp == 2) && + (realDirFlag == 1)) { + *tp++ = 0; + treeCreate = TRUE; + treeStartp = realPathp + (tp - spacep->data); + + if (*tp && !smb_IsLegalFilename(tp)) { + if(baseFid != 0) smb_ReleaseFID(baseFidp); + cm_ReleaseUser(userp); + free(realPathp); + return CM_ERROR_BADNTFILENAME; + } + } + else + break; + } - if (baseFid != 0) smb_ReleaseFID(baseFidp); + if (baseFid != 0) smb_ReleaseFID(baseFidp); - if (code) { - osi_Log0(afsd_logp,"NTCreateX parent not found"); - cm_ReleaseUser(userp); - free(realPathp); - return code; - } + if (code) { + osi_Log0(afsd_logp,"NTCreateX parent not found"); + cm_ReleaseUser(userp); + free(realPathp); + return code; + } - if(treeCreate && dscp->fileType == CM_SCACHETYPE_FILE) { - /* A file exists where we want a directory. */ - cm_ReleaseSCache(dscp); - cm_ReleaseUser(userp); - free(realPathp); - return CM_ERROR_EXISTS; - } + if(treeCreate && dscp->fileType == CM_SCACHETYPE_FILE) { + /* A file exists where we want a directory. */ + cm_ReleaseSCache(dscp); + cm_ReleaseUser(userp); + free(realPathp); + return CM_ERROR_EXISTS; + } - if (!lastNamep) lastNamep = realPathp; - else lastNamep++; + if (!lastNamep) lastNamep = realPathp; + else lastNamep++; - if (!smb_IsLegalFilename(lastNamep)) { + if (!smb_IsLegalFilename(lastNamep)) { + cm_ReleaseSCache(dscp); + cm_ReleaseUser(userp); + free(realPathp); + return CM_ERROR_BADNTFILENAME; + } + + if (!foundscp && !treeCreate) { + code = cm_Lookup(dscp, lastNamep, + CM_FLAG_FOLLOW | CM_FLAG_CASEFOLD, + userp, &req, &scp); + if (code && code != CM_ERROR_NOSUCHFILE) { cm_ReleaseSCache(dscp); cm_ReleaseUser(userp); free(realPathp); - return CM_ERROR_BADNTFILENAME; - } - - if (!foundscp && !treeCreate) { - code = cm_Lookup(dscp, lastNamep, - CM_FLAG_FOLLOW | CM_FLAG_CASEFOLD, - userp, &req, &scp); - if (code && code != CM_ERROR_NOSUCHFILE) { - cm_ReleaseSCache(dscp); - cm_ReleaseUser(userp); - free(realPathp); - return code; - } + return code; } } + } else { 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 - * by dscp, or we may have found the file directly. If code is non-zero, - * scp is NULL. - */ + * scp. Otherwise, we have to create it. The dir may be represented + * by dscp, or we may have found the file directly. If code is non-zero, + * scp is NULL. + */ if (code == 0 && !treeCreate) { code = cm_CheckNTOpen(scp, desiredAccess, createDisp, userp, - &req); + &req); if (code) { if (dscp) cm_ReleaseSCache(dscp); cm_ReleaseSCache(scp); @@ -3372,13 +3362,13 @@ long smb_ReceiveNTCreateX(smb_vc_t *vcp, smb_packet_t *inp, smb_packet_t *outp) } if (createDisp == 4 - || createDisp == 5) { - setAttr.mask = CM_ATTRMASK_LENGTH; - setAttr.length.LowPart = 0; - setAttr.length.HighPart = 0; - code = cm_SetAttr(scp, &setAttr, userp, &req); - openAction = 3; /* truncated existing file */ - } + || createDisp == 5) { + setAttr.mask = CM_ATTRMASK_LENGTH; + setAttr.length.LowPart = 0; + setAttr.length.HighPart = 0; + code = cm_SetAttr(scp, &setAttr, userp, &req); + openAction = 3; /* truncated existing file */ + } else openAction = 1; /* found existing file */ } else if (createDisp == 1 || createDisp == 4) { @@ -3391,53 +3381,53 @@ long smb_ReceiveNTCreateX(smb_vc_t *vcp, smb_packet_t *inp, smb_packet_t *outp) else if (realDirFlag == 0 || realDirFlag == -1) { osi_assert(dscp != NULL); osi_Log1(afsd_logp, "smb_ReceiveNTCreateX creating file %s", - osi_LogSaveString(afsd_logp, lastNamep)); + osi_LogSaveString(afsd_logp, lastNamep)); openAction = 2; /* created file */ setAttr.mask = CM_ATTRMASK_CLIENTMODTIME; setAttr.clientModTime = time(NULL); code = cm_Create(dscp, lastNamep, 0, &setAttr, &scp, userp, - &req); + &req); if (code == 0 && (dscp->flags & CM_SCACHEFLAG_ANYWATCH)) smb_NotifyChange(FILE_ACTION_ADDED, - FILE_NOTIFY_CHANGE_FILE_NAME, - dscp, lastNamep, NULL, TRUE); + FILE_NOTIFY_CHANGE_FILE_NAME, + dscp, lastNamep, NULL, TRUE); if (code == CM_ERROR_EXISTS && createDisp != 2) { /* 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 - * fails, that means that the file was deleted after we - * started this call. - */ + * creating it already, then we open it anyway. We + * don't bother retrying after this, since if this next + * fails, that means that the file was deleted after we + * started this call. + */ code = cm_Lookup(dscp, lastNamep, CM_FLAG_CASEFOLD, - userp, &req, &scp); + userp, &req, &scp); if (code == 0) { if (createDisp == 5) { setAttr.mask = CM_ATTRMASK_LENGTH; setAttr.length.LowPart = 0; setAttr.length.HighPart = 0; code = cm_SetAttr(scp, &setAttr, userp, - &req); + &req); } } /* lookup succeeded */ } } else { - char *tp, *pp; - char *cp; /* This component */ - int clen; /* length of component */ - cm_scache_t *tscp; - int isLast = 0; - - /* create directory */ - if(!treeCreate) treeStartp = lastNamep; - osi_assert(dscp != NULL); - osi_Log1(afsd_logp, "smb_ReceiveNTCreateX creating directory [%s]", - osi_LogSaveString(afsd_logp, treeStartp)); + char *tp, *pp; + char *cp; /* This component */ + int clen = 0; /* length of component */ + cm_scache_t *tscp; + int isLast = 0; + + /* create directory */ + if ( !treeCreate ) treeStartp = lastNamep; + osi_assert(dscp != NULL); + osi_Log1(afsd_logp, "smb_ReceiveNTCreateX creating directory [%s]", + osi_LogSaveString(afsd_logp, treeStartp)); openAction = 2; /* created directory */ setAttr.mask = CM_ATTRMASK_CLIENTMODTIME; setAttr.clientModTime = time(NULL); - + pp = treeStartp; cp = spacep->data; tscp = dscp; @@ -3446,6 +3436,7 @@ long smb_ReceiveNTCreateX(smb_vc_t *vcp, smb_packet_t *inp, smb_packet_t *outp) tp = strchr(pp, '\\'); if(!tp) { strcpy(cp,pp); + clen = strlen(cp); isLast = 1; /* indicate last component. the supplied path never ends in a slash */ } else { @@ -3493,7 +3484,7 @@ long smb_ReceiveNTCreateX(smb_vc_t *vcp, smb_packet_t *inp, smb_packet_t *outp) if (code) { /* something went wrong creating or truncating the file */ if (scp) cm_ReleaseSCache(scp); - if (dscp) cm_ReleaseSCache(dscp); + if (dscp) cm_ReleaseSCache(dscp); cm_ReleaseUser(userp); free(realPathp); return code; @@ -3502,15 +3493,15 @@ long smb_ReceiveNTCreateX(smb_vc_t *vcp, smb_packet_t *inp, smb_packet_t *outp) /* make sure we have file vs. dir right (only applies for single component case) */ if (realDirFlag == 0 && scp->fileType != CM_SCACHETYPE_FILE) { cm_ReleaseSCache(scp); - if (dscp) cm_ReleaseSCache(dscp); + if (dscp) cm_ReleaseSCache(dscp); cm_ReleaseUser(userp); free(realPathp); return CM_ERROR_ISDIR; } - /* (only applies for single component case) */ + /* (only applies to single component case) */ if (realDirFlag == 1 && scp->fileType == CM_SCACHETYPE_FILE) { cm_ReleaseSCache(scp); - if (dscp) cm_ReleaseSCache(dscp); + if (dscp) cm_ReleaseSCache(dscp); cm_ReleaseUser(userp); free(realPathp); return CM_ERROR_NOTDIR; @@ -3552,7 +3543,7 @@ long smb_ReceiveNTCreateX(smb_vc_t *vcp, smb_packet_t *inp, smb_packet_t *outp) smb_SetSMBParmDouble(outp, parmSlot, (char *)&ft); parmSlot += 4; smb_SetSMBParmDouble(outp, parmSlot, (char *)&ft); parmSlot += 4; smb_SetSMBParmLong(outp, parmSlot, smb_ExtAttributes(scp)); - parmSlot += 2; + parmSlot += 2; smb_SetSMBParmDouble(outp, parmSlot, (char *)&scp->length); parmSlot += 4; smb_SetSMBParmDouble(outp, parmSlot, (char *)&scp->length); parmSlot += 4; smb_SetSMBParm(outp, parmSlot, 0); parmSlot++; /* filetype */ @@ -3563,13 +3554,13 @@ long smb_ReceiveNTCreateX(smb_vc_t *vcp, smb_packet_t *inp, smb_packet_t *outp) smb_SetSMBDataLength(outp, 0); osi_Log2(afsd_logp, "SMB NT CreateX opening fid %d path %s", fidp->fid, - osi_LogSaveString(afsd_logp, realPathp)); + osi_LogSaveString(afsd_logp, realPathp)); smb_ReleaseFID(fidp); 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; @@ -3594,14 +3585,18 @@ long smb_ReceiveNTTranCreate(smb_vc_t *vcp, smb_packet_t *inp, smb_packet_t *out unsigned int requestOpLock; unsigned int requestBatchOpLock; unsigned int mustBeDir; - unsigned int extendedRespRequired; + unsigned int extendedRespRequired; int realDirFlag; unsigned int desiredAccess; - /*unsigned int allocSize;*/ - /*unsigned int shareAccess;*/ +#ifdef DEBUG_VERBOSE + unsigned int allocSize; + unsigned int shareAccess; +#endif unsigned int extAttributes; unsigned int createDisp; - /*unsigned int sdLen;*/ +#ifdef DEBUG_VERBOSE + unsigned int sdLen; +#endif unsigned int createOptions; int initialModeBits; unsigned short baseFid; @@ -3634,7 +3629,7 @@ long smb_ReceiveNTTranCreate(smb_vc_t *vcp, smb_packet_t *inp, smb_packet_t *out requestOpLock = flags & 0x02; requestBatchOpLock = flags & 0x04; mustBeDir = flags & 0x08; - extendedRespRequired = flags & 0x10; + extendedRespRequired = flags & 0x10; /* * Why all of a sudden 32-bit FID? @@ -3644,19 +3639,25 @@ long smb_ReceiveNTTranCreate(smb_vc_t *vcp, smb_packet_t *inp, smb_packet_t *out return CM_ERROR_INVAL; baseFid = (unsigned short)lparmp[1]; desiredAccess = lparmp[2]; - /*allocSize = lparmp[3];*/ +#ifdef DEBUG_VERBOSE + allocSize = lparmp[3]; +#endif /* DEBUG_VERSOSE */ extAttributes = lparmp[5]; - /*shareAccess = lparmp[6];*/ +#ifdef DEBUG_VEROSE + shareAccess = lparmp[6]; +#endif createDisp = lparmp[7]; createOptions = lparmp[8]; - /*sdLen = lparmp[9];*/ +#ifdef DEBUG_VERBOSE + sdLen = lparmp[9]; +#endif nameLength = lparmp[11]; - /* +#ifdef DEBUG_VERBOSE osi_Log4(afsd_logp,"NTTransCreate with da[%x],ea[%x],sa[%x],cd[%x]",desiredAccess,extAttributes,shareAccess,createDisp); osi_Log2(afsd_logp,"... co[%x],sdl[%x],as[%x]",createOptions,sdLen,allocSize); osi_Log1(afsd_logp,"... flags[%x]",flags); - */ +#endif /* mustBeDir is never set; createOptions directory bit seems to be * more important @@ -3688,6 +3689,7 @@ long smb_ReceiveNTTranCreate(smb_vc_t *vcp, smb_packet_t *inp, smb_packet_t *out * Nothing here to handle SMB_IOCTL_FILENAME. * Will add it if necessary. */ + #ifdef DEBUG_VERBOSE { char *hexp, *asciip; @@ -3699,36 +3701,36 @@ long smb_ReceiveNTTranCreate(smb_vc_t *vcp, smb_packet_t *inp, smb_packet_t *out #endif userp = smb_GetUser(vcp, inp); - if(!userp) { - osi_Log1(afsd_logp, "NTTranCreate invalid user [%d]", ((smb_t *) inp)->uid); - free(realPathp); - return CM_ERROR_INVAL; - } + if(!userp) { + osi_Log1(afsd_logp, "NTTranCreate invalid user [%d]", ((smb_t *) inp)->uid); + free(realPathp); + return CM_ERROR_INVAL; + } if (baseFid == 0) { baseDirp = cm_rootSCachep; tidPathp = smb_GetTIDPath(vcp, ((smb_t *)inp)->tid); } else { - baseFidp = smb_FindFID(vcp, baseFid, 0); - if(!baseFidp) { - osi_Log1(afsd_logp, "NTTranCreate Invalid fid [%d]", baseFid); - free(realPathp); - cm_ReleaseUser(userp); - return CM_ERROR_INVAL; - } + baseFidp = smb_FindFID(vcp, baseFid, 0); + if(!baseFidp) { + osi_Log1(afsd_logp, "NTTranCreate Invalid fid [%d]", baseFid); + free(realPathp); + cm_ReleaseUser(userp); + return CM_ERROR_INVAL; + } baseDirp = baseFidp->scp; tidPathp = NULL; } - /* compute open mode */ - fidflags = 0; - if (desiredAccess & DELETE) - fidflags |= SMB_FID_OPENDELETE; - if (desiredAccess & AFS_ACCESS_READ) - fidflags |= SMB_FID_OPENREAD; - if (desiredAccess & AFS_ACCESS_WRITE) - fidflags |= SMB_FID_OPENWRITE; + /* compute open mode */ + fidflags = 0; + if (desiredAccess & DELETE) + fidflags |= SMB_FID_OPENDELETE; + if (desiredAccess & AFS_ACCESS_READ) + fidflags |= SMB_FID_OPENREAD; + if (desiredAccess & AFS_ACCESS_WRITE) + fidflags |= SMB_FID_OPENWRITE; dscp = NULL; code = 0; @@ -3757,13 +3759,13 @@ long smb_ReceiveNTTranCreate(smb_vc_t *vcp, smb_packet_t *inp, smb_packet_t *out if (!lastNamep) lastNamep = realPathp; else lastNamep++; - if (!smb_IsLegalFilename(lastNamep)) - return CM_ERROR_BADNTFILENAME; + if (!smb_IsLegalFilename(lastNamep)) + return CM_ERROR_BADNTFILENAME; if (!foundscp) { code = cm_Lookup(dscp, lastNamep, - CM_FLAG_FOLLOW | CM_FLAG_CASEFOLD, - userp, &req, &scp); + CM_FLAG_FOLLOW | CM_FLAG_CASEFOLD, + userp, &req, &scp); if (code && code != CM_ERROR_NOSUCHFILE) { cm_ReleaseSCache(dscp); cm_ReleaseUser(userp); @@ -3825,7 +3827,7 @@ long smb_ReceiveNTTranCreate(smb_vc_t *vcp, smb_packet_t *inp, smb_packet_t *out else if (realDirFlag == 0 || realDirFlag == -1) { osi_assert(dscp != NULL); osi_Log1(afsd_logp, "smb_ReceiveNTTranCreate creating file %s", - osi_LogSaveString(afsd_logp, lastNamep)); + osi_LogSaveString(afsd_logp, lastNamep)); openAction = 2; /* created file */ setAttr.mask = CM_ATTRMASK_CLIENTMODTIME; setAttr.clientModTime = time(NULL); @@ -3913,13 +3915,13 @@ long smb_ReceiveNTTranCreate(smb_vc_t *vcp, smb_packet_t *inp, smb_packet_t *out fidp->flags = fidflags; - /* 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_dscp = dscp; - cm_HoldSCache(dscp); - fidp->NTopen_pathp = strdup(lastNamep); - } + /* 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_dscp = dscp; + cm_HoldSCache(dscp); + fidp->NTopen_pathp = strdup(lastNamep); + } fidp->NTopen_wholepathp = realPathp; /* we don't need this any longer */ @@ -3930,109 +3932,107 @@ long smb_ReceiveNTTranCreate(smb_vc_t *vcp, smb_packet_t *inp, smb_packet_t *out /* set inp->fid so that later read calls in same msg can find fid */ inp->fid = fidp->fid; - /* check whether we are required to send and extended response */ - if(!extendedRespRequired) { - /* out parms */ - parmOffset = 8*4 + 39; - parmOffset += 1; /* pad to 4 */ - dataOffset = parmOffset + 70; - - parmSlot = 1; - outp->oddByte = 1; - /* Total Parameter Count */ - smb_SetSMBParmLong(outp, parmSlot, 70); parmSlot += 2; - /* Total Data Count */ - smb_SetSMBParmLong(outp, parmSlot, 0); parmSlot += 2; - /* Parameter Count */ - smb_SetSMBParmLong(outp, parmSlot, 70); parmSlot += 2; - /* Parameter Offset */ - smb_SetSMBParmLong(outp, parmSlot, parmOffset); parmSlot += 2; - /* Parameter Displacement */ - smb_SetSMBParmLong(outp, parmSlot, 0); parmSlot += 2; - /* Data Count */ - smb_SetSMBParmLong(outp, parmSlot, 0); parmSlot += 2; - /* Data Offset */ - smb_SetSMBParmLong(outp, parmSlot, dataOffset); parmSlot += 2; - /* Data Displacement */ - smb_SetSMBParmLong(outp, parmSlot, 0); parmSlot += 2; - smb_SetSMBParmByte(outp, parmSlot, 0); /* Setup Count */ - smb_SetSMBDataLength(outp, 70); + /* check whether we are required to send an extended response */ + if (!extendedRespRequired) { + /* out parms */ + parmOffset = 8*4 + 39; + parmOffset += 1; /* pad to 4 */ + dataOffset = parmOffset + 70; + + parmSlot = 1; + outp->oddByte = 1; + /* Total Parameter Count */ + smb_SetSMBParmLong(outp, parmSlot, 70); parmSlot += 2; + /* Total Data Count */ + smb_SetSMBParmLong(outp, parmSlot, 0); parmSlot += 2; + /* Parameter Count */ + smb_SetSMBParmLong(outp, parmSlot, 70); parmSlot += 2; + /* Parameter Offset */ + smb_SetSMBParmLong(outp, parmSlot, parmOffset); parmSlot += 2; + /* Parameter Displacement */ + smb_SetSMBParmLong(outp, parmSlot, 0); parmSlot += 2; + /* Data Count */ + smb_SetSMBParmLong(outp, parmSlot, 0); parmSlot += 2; + /* Data Offset */ + smb_SetSMBParmLong(outp, parmSlot, dataOffset); parmSlot += 2; + /* Data Displacement */ + smb_SetSMBParmLong(outp, parmSlot, 0); parmSlot += 2; + smb_SetSMBParmByte(outp, parmSlot, 0); /* Setup Count */ + smb_SetSMBDataLength(outp, 70); - lock_ObtainMutex(&scp->mx); - outData = smb_GetSMBData(outp, NULL); - outData++; /* round to get to parmOffset */ - *outData = 0; outData++; /* oplock */ - *outData = 0; outData++; /* reserved */ - *((USHORT *)outData) = fidp->fid; outData += 2; /* fid */ - *((ULONG *)outData) = openAction; outData += 4; - *((ULONG *)outData) = 0; outData += 4; /* EA error offset */ - smb_LargeSearchTimeFromUnixTime(&ft, scp->clientModTime); - *((FILETIME *)outData) = ft; outData += 8; /* creation time */ - *((FILETIME *)outData) = ft; outData += 8; /* last access time */ - *((FILETIME *)outData) = ft; outData += 8; /* last write time */ - *((FILETIME *)outData) = ft; outData += 8; /* change time */ - *((ULONG *)outData) = smb_ExtAttributes(scp); outData += 4; - *((LARGE_INTEGER *)outData) = scp->length; outData += 8; /* alloc sz */ - *((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); - outData += 2; /* is a dir? */ - lock_ReleaseMutex(&scp->mx); - - } else { /* extended response required */ - - /* out parms */ - parmOffset = 8*4 + 39; - parmOffset += 1; /* pad to 4 */ - dataOffset = parmOffset + 104; - - parmSlot = 1; - outp->oddByte = 1; - /* Total Parameter Count */ - smb_SetSMBParmLong(outp, parmSlot, 101); parmSlot += 2; - /* Total Data Count */ - smb_SetSMBParmLong(outp, parmSlot, 0); parmSlot += 2; - /* Parameter Count */ - smb_SetSMBParmLong(outp, parmSlot, 101); parmSlot += 2; - /* Parameter Offset */ - smb_SetSMBParmLong(outp, parmSlot, parmOffset); parmSlot += 2; - /* Parameter Displacement */ - smb_SetSMBParmLong(outp, parmSlot, 0); parmSlot += 2; - /* Data Count */ - smb_SetSMBParmLong(outp, parmSlot, 0); parmSlot += 2; - /* Data Offset */ - smb_SetSMBParmLong(outp, parmSlot, dataOffset); parmSlot += 2; - /* Data Displacement */ - smb_SetSMBParmLong(outp, parmSlot, 0); parmSlot += 2; - smb_SetSMBParmByte(outp, parmSlot, 0); /* Setup Count */ - smb_SetSMBDataLength(outp, 105); - - lock_ObtainMutex(&scp->mx); - outData = smb_GetSMBData(outp, NULL); - outData++; /* round to get to parmOffset */ - *outData = 0; outData++; /* oplock */ - *outData = 1; outData++; /* response type */ - *((USHORT *)outData) = fidp->fid; outData += 2; /* fid */ - *((ULONG *)outData) = openAction; outData += 4; - *((ULONG *)outData) = 0; outData += 4; /* EA error offset */ - smb_LargeSearchTimeFromUnixTime(&ft, scp->clientModTime); - *((FILETIME *)outData) = ft; outData += 8; /* creation time */ - *((FILETIME *)outData) = ft; outData += 8; /* last access time */ - *((FILETIME *)outData) = ft; outData += 8; /* last write time */ - *((FILETIME *)outData) = ft; outData += 8; /* change time */ - *((ULONG *)outData) = smb_ExtAttributes(scp); outData += 4; - *((LARGE_INTEGER *)outData) = scp->length; outData += 8; /* alloc sz */ - *((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); - outData += 1; /* is a dir? */ - memset(outData,0,24); outData += 24; /* Volume ID and file ID */ - *((ULONG *)outData) = 0x001f01ffL; outData += 4; /* Maxmimal access rights */ - *((ULONG *)outData) = 0; outData += 4; /* Guest Access rights */ - lock_ReleaseMutex(&scp->mx); - } + lock_ObtainMutex(&scp->mx); + outData = smb_GetSMBData(outp, NULL); + outData++; /* round to get to parmOffset */ + *outData = 0; outData++; /* oplock */ + *outData = 0; outData++; /* reserved */ + *((USHORT *)outData) = fidp->fid; outData += 2; /* fid */ + *((ULONG *)outData) = openAction; outData += 4; + *((ULONG *)outData) = 0; outData += 4; /* EA error offset */ + smb_LargeSearchTimeFromUnixTime(&ft, scp->clientModTime); + *((FILETIME *)outData) = ft; outData += 8; /* creation time */ + *((FILETIME *)outData) = ft; outData += 8; /* last access time */ + *((FILETIME *)outData) = ft; outData += 8; /* last write time */ + *((FILETIME *)outData) = ft; outData += 8; /* change time */ + *((ULONG *)outData) = smb_ExtAttributes(scp); outData += 4; + *((LARGE_INTEGER *)outData) = scp->length; outData += 8; /* alloc sz */ + *((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); + outData += 2; /* is a dir? */ + lock_ReleaseMutex(&scp->mx); + } else { + /* out parms */ + parmOffset = 8*4 + 39; + parmOffset += 1; /* pad to 4 */ + dataOffset = parmOffset + 104; + + parmSlot = 1; + outp->oddByte = 1; + /* Total Parameter Count */ + smb_SetSMBParmLong(outp, parmSlot, 101); parmSlot += 2; + /* Total Data Count */ + smb_SetSMBParmLong(outp, parmSlot, 0); parmSlot += 2; + /* Parameter Count */ + smb_SetSMBParmLong(outp, parmSlot, 101); parmSlot += 2; + /* Parameter Offset */ + smb_SetSMBParmLong(outp, parmSlot, parmOffset); parmSlot += 2; + /* Parameter Displacement */ + smb_SetSMBParmLong(outp, parmSlot, 0); parmSlot += 2; + /* Data Count */ + smb_SetSMBParmLong(outp, parmSlot, 0); parmSlot += 2; + /* Data Offset */ + smb_SetSMBParmLong(outp, parmSlot, dataOffset); parmSlot += 2; + /* Data Displacement */ + smb_SetSMBParmLong(outp, parmSlot, 0); parmSlot += 2; + smb_SetSMBParmByte(outp, parmSlot, 0); /* Setup Count */ + smb_SetSMBDataLength(outp, 105); + + lock_ObtainMutex(&scp->mx); + outData = smb_GetSMBData(outp, NULL); + outData++; /* round to get to parmOffset */ + *outData = 0; outData++; /* oplock */ + *outData = 1; outData++; /* response type */ + *((USHORT *)outData) = fidp->fid; outData += 2; /* fid */ + *((ULONG *)outData) = openAction; outData += 4; + *((ULONG *)outData) = 0; outData += 4; /* EA error offset */ + smb_LargeSearchTimeFromUnixTime(&ft, scp->clientModTime); + *((FILETIME *)outData) = ft; outData += 8; /* creation time */ + *((FILETIME *)outData) = ft; outData += 8; /* last access time */ + *((FILETIME *)outData) = ft; outData += 8; /* last write time */ + *((FILETIME *)outData) = ft; outData += 8; /* change time */ + *((ULONG *)outData) = smb_ExtAttributes(scp); outData += 4; + *((LARGE_INTEGER *)outData) = scp->length; outData += 8; /* alloc sz */ + *((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); + outData += 1; /* is a dir? */ + memset(outData,0,24); outData += 24; /* Volume ID and file ID */ + *((ULONG *)outData) = 0x001f01ffL; outData += 4; /* Maxmimal access rights */ + *((ULONG *)outData) = 0; outData += 4; /* Guest Access rights */ + lock_ReleaseMutex(&scp->mx); + } osi_Log1(afsd_logp, "SMB NTTranCreate opening fid %d", fidp->fid); @@ -4040,8 +4040,7 @@ long smb_ReceiveNTTranCreate(smb_vc_t *vcp, smb_packet_t *inp, smb_packet_t *out cm_ReleaseUser(userp); - /* free(realPathp); Can't free realPathp here because fidp->NTopen_wholepathp points there */ - + /* free(realPathp); Can't free realPathp here because fidp->NTopen_wholepathp points there */ /* leave scp held since we put it in fidp->scp */ return 0; } @@ -4053,18 +4052,17 @@ long smb_ReceiveNTTranNotifyChange(smb_vc_t *vcp, smb_packet_t *inp, ULONG filter; USHORT fid, watchtree; smb_fid_t *fidp; cm_scache_t *scp; - + filter = smb_GetSMBParm(inp, 19) | (smb_GetSMBParm(inp, 20) << 16); fid = smb_GetSMBParm(inp, 21); - watchtree = smb_GetSMBParm(inp, 22) && 0xffff; /* TODO: should this be 0xff ? */ + watchtree = smb_GetSMBParm(inp, 22) && 0xffff; /* TODO: should this be 0xff ? */ - fidp = smb_FindFID(vcp, fid, 0); - - if(!fidp) { - osi_Log1(afsd_logp, "ERROR: NotifyChange given invalid fid [%d]", fid); - return CM_ERROR_BADFD; - } + fidp = smb_FindFID(vcp, fid, 0); + if (!fidp) { + osi_Log1(afsd_logp, "ERROR: NotifyChange given invalid fid [%d]", fid); + return CM_ERROR_BADFD; + } savedPacketp = smb_CopyPacket(inp); savedPacketp->vcp = vcp; /* TODO: refcount vcp? */ @@ -4073,20 +4071,19 @@ long smb_ReceiveNTTranNotifyChange(smb_vc_t *vcp, smb_packet_t *inp, smb_Directory_Watches = savedPacketp; lock_ReleaseMutex(&smb_Dir_Watch_Lock); - osi_Log4(afsd_logp, "Request for NotifyChange filter 0x%x fid %d wtree %d file %s", - filter, fid, watchtree, osi_LogSaveString(afsd_logp, fidp->NTopen_wholepathp)); + osi_Log4(afsd_logp, "Request for NotifyChange filter 0x%x fid %d wtree %d file %s", + filter, fid, watchtree, osi_LogSaveString(afsd_logp, fidp->NTopen_wholepathp)); - scp = fidp->scp; - lock_ObtainMutex(&scp->mx); - if (watchtree) - scp->flags |= CM_SCACHEFLAG_WATCHEDSUBTREE; - else - scp->flags |= CM_SCACHEFLAG_WATCHED; - lock_ReleaseMutex(&scp->mx); - smb_ReleaseFID(fidp); + scp = fidp->scp; + lock_ObtainMutex(&scp->mx); + if (watchtree) + scp->flags |= CM_SCACHEFLAG_WATCHEDSUBTREE; + else + scp->flags |= CM_SCACHEFLAG_WATCHED; + lock_ReleaseMutex(&scp->mx); + smb_ReleaseFID(fidp); outp->flags |= SMB_PACKETFLAG_NOSEND; - return 0; } @@ -4232,7 +4229,7 @@ void smb_NotifyChange(DWORD action, DWORD notifyFilter, filter = smb_GetSMBParm(watch, 19) | (smb_GetSMBParm(watch, 20) << 16); fid = smb_GetSMBParm(watch, 21); - wtree = smb_GetSMBParm(watch, 22) & 0xffff; /* TODO: should this be 0xff ? */ + 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; @@ -4245,11 +4242,11 @@ void smb_NotifyChange(DWORD action, DWORD notifyFilter, filter = 0x17; fidp = smb_FindFID(vcp, fid, 0); - if(!fidp) { - lastWatch = watch; - watch = watch->nextp; - continue; - } + if (!fidp) { + lastWatch = watch; + watch = watch->nextp; + continue; + } if (fidp->scp != dscp || (filter & notifyFilter) == 0 || (!isDirectParent && !wtree)) { @@ -4399,22 +4396,22 @@ long smb_ReceiveNTCancel(smb_vc_t *vcp, smb_packet_t *inp, smb_packet_t *outp) watchtree = smb_GetSMBParm(watch, 22) & 0xffff; fidp = smb_FindFID(vcp, fid, 0); - if(fidp) { - osi_Log3(afsd_logp, "Cancelling change notification for fid %d wtree %d file %s", - fid, watchtree, - osi_LogSaveString(afsd_logp, fidp->NTopen_wholepathp)); - - scp = fidp->scp; - lock_ObtainMutex(&scp->mx); - if (watchtree) - scp->flags &= ~CM_SCACHEFLAG_WATCHEDSUBTREE; - else - scp->flags &= ~CM_SCACHEFLAG_WATCHED; - lock_ReleaseMutex(&scp->mx); - smb_ReleaseFID(fidp); - } else { - osi_Log2(afsd_logp,"NTCancel unable to resolve fid [%d] in vcp[%x]", fid,vcp); - } + if (fidp) { + osi_Log3(afsd_logp, "Cancelling change notification for fid %d wtree %d file %s", + fid, watchtree, + osi_LogSaveString(afsd_logp, (fidp)?fidp->NTopen_wholepathp:"")); + + scp = fidp->scp; + lock_ObtainMutex(&scp->mx); + if (watchtree) + scp->flags &= ~CM_SCACHEFLAG_WATCHEDSUBTREE; + else + scp->flags &= ~CM_SCACHEFLAG_WATCHED; + lock_ReleaseMutex(&scp->mx); + smb_ReleaseFID(fidp); + } else { + osi_Log2(afsd_logp,"NTCancel unable to resolve fid [%d] in vcp[%x]", fid,vcp); + } /* assume STATUS32; return 0xC0000120 (CANCELED) */ replyWctp = watch->wctp; @@ -4445,7 +4442,6 @@ void smb3_Init() cm_user_t *smb_FindCMUserByName(/*smb_vc_t *vcp,*/ char *usern, char *machine) { - cm_user_t *userp; /*int newUid;*/ smb_username_t *unp; @@ -4454,9 +4450,9 @@ cm_user_t *smb_FindCMUserByName(/*smb_vc_t *vcp,*/ char *usern, char *machine) lock_ObtainMutex(&unp->mx); unp->userp = cm_NewUser(); lock_ReleaseMutex(&unp->mx); - osi_LogEvent("AFS smb_FindCMUserByName New User",NULL,"name[%s] machine[%s]",usern,machine); + osi_LogEvent("AFS smb_FindCMUserByName : New User",NULL,"name[%s] machine[%s]",usern,machine); } else { - osi_LogEvent("AFS smb_FindCMUserByName Found",NULL,"name[%s] machine[%s]",usern,machine); + osi_LogEvent("AFS smb_FindCMUserByName : Found",NULL,"name[%s] machine[%s]",usern,machine); } return unp->userp; } -- 1.9.4