* directory or online at http://www.openafs.org/dl/license10.html
*/
+//#define NOSERVICE 1
+
#include <afs/param.h>
#include <afs/stds.h>
+#ifndef DJGPP
#include <windows.h>
+#endif /* !DJGPP */
#include <stdlib.h>
#include <malloc.h>
#include <string.h>
cm_user_t *smb_GetTran2User(smb_vc_t *vcp, smb_tran2Packet_t *inp)
{
smb_user_t *uidp;
- cm_user_t *up;
+ cm_user_t *up = NULL;
uidp = smb_FindUID(vcp, inp->uid, 0);
if (!uidp) return NULL;
lock_ObtainMutex(&uidp->mx);
- up = uidp->userp;
- cm_HoldUser(up);
+ if (uidp->unp) {
+ up = uidp->unp->userp;
+ cm_HoldUser(up);
+ }
lock_ReleaseMutex(&uidp->mx);
smb_ReleaseUID(uidp);
long smb_ReceiveV3SessionSetupX(smb_vc_t *vcp, smb_packet_t *inp, smb_packet_t *outp)
{
- char *tp;
- char *usern, *pwd, *pwdx;
- smb_user_t *uidp, *dead_uidp;
- unsigned short newUid;
- unsigned long caps;
- cm_user_t *userp;
- char *s1 = " ";
-
- /* Check for bad conns */
- if (vcp->flags & SMB_VCFLAG_REMOTECONN)
- return CM_ERROR_REMOTECONN;
-
- /* For NT LM 0.12 and up, get capabilities */
- if (vcp->flags & SMB_VCFLAG_USENT) {
- caps = smb_GetSMBParm(inp, 11);
- if (caps & 0x40)
- vcp->flags |= SMB_VCFLAG_STATUS32;
- /* for now, ignore other capability bits */
- }
-
- /* Parse the data */
- tp = smb_GetSMBData(inp, NULL);
- if (vcp->flags & SMB_VCFLAG_USENT)
- pwdx = smb_ParseString(tp, &tp);
- pwd = smb_ParseString(tp, &tp);
- usern = smb_ParseString(tp, &tp);
-
- /* Create a new UID and cm_user_t structure */
- userp = cm_NewUser();
- lock_ObtainMutex(&vcp->mx);
- newUid = vcp->uidCounter++;
- lock_ReleaseMutex(&vcp->mx);
-
- /* Create a new smb_user_t structure and connect them up */
- uidp = smb_FindUID(vcp, newUid, SMB_FLAG_CREATE);
- lock_ObtainMutex(&uidp->mx);
- uidp->userp = userp;
- uidp->name = strdup(usern);
- lock_ReleaseMutex(&uidp->mx);
- smb_ReleaseUID(uidp);
-
- if (dead_vcp) {
- dead_uidp = dead_vcp->usersp;
- while (dead_uidp) {
- if (dead_uidp->userp
- && strcmp(dead_uidp->name, usern) == 0)
- break;
- dead_uidp = dead_uidp->nextp;
- }
- }
-
- /* transfer tokens from dead vcp */
- if (dead_vcp && dead_uidp) {
- cm_user_t *dead_userp;
- s1 = ", tokens from terminated session";
- dead_userp = dead_uidp->userp;
- cm_ResetACLCache(dead_userp);
- userp->cellInfop = dead_userp->cellInfop;
- dead_userp->cellInfop = NULL;
- dead_vcp = NULL;
- }
-
- /* transfer tokens from integrated logon */
- if (vcp->logonDLLUser) {
- s1 = ", tokens from integrated logon";
- cm_ResetACLCache(vcp->logonDLLUser);
- userp->cellInfop = vcp->logonDLLUser->cellInfop;
- vcp->logonDLLUser->cellInfop = NULL;
- vcp->logonDLLUser = NULL;
- }
-
- /* transfer tokens for logoff profile upload */
- if (vcp->justLoggedOut) {
- cm_user_t *logout_userp;
- if (GetTickCount() - vcp->logoffTime <
- 1000 * smb_LogoffTransferTimeout
- && strcmp(vcp->justLoggedOut->name, usern) == 0) {
- s1 = ", tokens from logoff";
- logout_userp = vcp->justLoggedOut->userp;
- cm_ResetACLCache(logout_userp);
- userp->cellInfop = logout_userp->cellInfop;
- logout_userp->cellInfop = NULL;
- }
- vcp->justLoggedOut = NULL;
- }
- else if (loggedOut) {
- cm_user_t *logout_userp;
- if (GetTickCount() - loggedOutTime <
- 1000 * smb_LogoffTransferTimeout
- && strcmp(loggedOutName, usern) == 0) {
- s1 = ", tokens from logoff";
- logout_userp = loggedOutUserp->userp;
- cm_ResetACLCache(logout_userp);
- userp->cellInfop = logout_userp->cellInfop;
- logout_userp->cellInfop = NULL;
- }
- smb_ReleaseUID(loggedOutUserp);
- loggedOutUserp = NULL;
- free(loggedOutName);
- loggedOutName = NULL;
- loggedOut = 0;
- }
-
- /* Return UID to the client */
- ((smb_t *)outp)->uid = newUid;
- /* Also to the next chained message */
- ((smb_t *)inp)->uid = newUid;
-
- osi_Log3(afsd_logp, "SMB3 session setup name %s creating ID %d%s",
- osi_LogSaveString(afsd_logp, usern), newUid, osi_LogSaveString(afsd_logp, s1));
- smb_SetSMBParm(outp, 2, 0);
- smb_SetSMBDataLength(outp, 0);
- return 0;
+ char *tp;
+ char *usern, *pwd, *pwdx;
+ smb_user_t *uidp, *dead_uidp;
+ unsigned short newUid;
+ unsigned long caps;
+ cm_user_t *userp;
+ smb_username_t *unp;
+ char *s1 = " ";
+
+ /* Check for bad conns */
+ if (vcp->flags & SMB_VCFLAG_REMOTECONN)
+ return CM_ERROR_REMOTECONN;
+
+ /* For NT LM 0.12 and up, get capabilities */
+ if (vcp->flags & SMB_VCFLAG_USENT) {
+ caps = smb_GetSMBParm(inp, 11);
+ if (caps & 0x40)
+ vcp->flags |= SMB_VCFLAG_STATUS32;
+ /* for now, ignore other capability bits */
+ }
+
+ /* Parse the data */
+ tp = smb_GetSMBData(inp, NULL);
+ if (vcp->flags & SMB_VCFLAG_USENT)
+ pwdx = smb_ParseString(tp, &tp);
+ pwd = smb_ParseString(tp, &tp);
+ usern = smb_ParseString(tp, &tp);
+
+ /* On Windows 2000, this function appears to be called more often than
+ it is expected to be called. This resulted in multiple smb_user_t
+ records existing all for the same user session which results in all
+ of the users tokens disappearing.
+
+ To avoid this problem, we look for an existing smb_user_t record
+ based on the users name, and use that one if we find it.
+ */
+
+ uidp = smb_FindUserByNameThisSession(vcp, usern);
+ if (uidp) { /* already there, so don't create a new one */
+ unp = uidp->unp;
+ userp = unp->userp;
+ newUid = (unsigned short)uidp->userID; /* For some reason these are different types!*/
+ osi_LogEvent("AFS smb_ReceiveV3SessionSetupX",NULL,"FindUserByName:Lana[%d],lsn[%d],userid[%d],name[%s]",vcp->lana,vcp->lsn,newUid,usern);
+ osi_Log3(afsd_logp,"smb_ReceiveV3SessionSetupX FindUserByName:Lana[%d],lsn[%d],userid[%d]",vcp->lana,vcp->lsn,newUid);
+ smb_ReleaseUID(uidp);
+ }
+ else {
+ /* do a global search for the username/machine name pair */
+ unp = smb_FindUserByName(usern, vcp->rname, SMB_FLAG_CREATE);
+
+ /* Create a new UID and cm_user_t structure */
+ userp = unp->userp;
+ if (!userp)
+ userp = cm_NewUser();
+ lock_ObtainMutex(&vcp->mx);
+ 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);
+ unp->userp = userp;
+ lock_ReleaseMutex(&unp->mx);
+
+ 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_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);
+ }
+
+ /* Return UID to the client */
+ ((smb_t *)outp)->uid = newUid;
+ /* Also to the next chained message */
+ ((smb_t *)inp)->uid = newUid;
+
+ osi_Log3(afsd_logp, "SMB3 session setup name %s creating ID %d%s",
+ osi_LogSaveString(afsd_logp, usern), newUid, osi_LogSaveString(afsd_logp, s1));
+ smb_SetSMBParm(outp, 2, 0);
+ smb_SetSMBDataLength(outp, 0);
+ return 0;
}
long smb_ReceiveV3UserLogoffX(smb_vc_t *vcp, smb_packet_t *inp, smb_packet_t *outp)
if (uidp) {
char *s1 = NULL, *s2 = NULL;
- /* Also, this is not logon session any more */
- if (uidp->userp == vcp->logonDLLUser) {
- s1 = ", was logon session";
- vcp->logonDLLUser = NULL;
- }
-
- /* But its tokens might be needed later */
- if (uidp->userp && !(uidp->userp->flags & CM_USERFLAG_WASLOGON)
- && smb_LogoffTokenTransfer) {
- s2 = ", pre-logout effect";
- vcp->justLoggedOut = uidp;
- vcp->logoffTime = GetTickCount();
- }
-
if (s2 == NULL) s2 = " ";
if (s1 == NULL) {s1 = s2; s2 = " ";}
osi_Log4(afsd_logp, "SMB3 user logoffX uid %d name %s%s%s",
uidp->userID,
- osi_LogSaveString(afsd_logp, uidp->name),
- s1, s2);
+ osi_LogSaveString(afsd_logp,
+ (uidp->unp) ? uidp->unp->name: " "), s1, s2);
lock_ObtainMutex(&uidp->mx);
uidp->flags |= SMB_USERFLAG_DELETE;
/* We sometimes see 0 word count. What to do? */
if (*inp->wctp == 0) {
+#ifndef DJGPP
HANDLE h;
char *ptbuf[1];
ReportEvent(h, EVENTLOG_WARNING_TYPE, 0, 1003, NULL,
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);
lock_ReleaseWrite(&smb_globalLock);
/* now dispatch it */
+ 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);
/* if an error is returned, we're supposed to send an error packet,
size_t shortNameLen;
};
-long cm_GetShortNameProc(cm_scache_t *scp, cm_dirEntry_t *dep, void *vrockp,
+int cm_GetShortNameProc(cm_scache_t *scp, cm_dirEntry_t *dep, void *vrockp,
osi_hyper_t *offp)
{
struct smb_ShortNameRock *rockp;
spacep = cm_GetSpace();
smb_StripLastComponent(spacep->data, &lastComp,
(char *)(&p->parmsp[3]));
- if (strcmp(lastComp, "\\desktop.ini") == 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
smb_FreeTran2Packet(outp);
return 0;
}
-
+
lock_ObtainMutex(&scp->mx);
code = cm_SyncOp(scp, NULL, userp, &req, 0,
CM_SCACHESYNC_NEEDCALLBACK | CM_SCACHESYNC_GETSTATUS);
if (infoLevel == 0x108) {
code = cm_GetShortName((char *)(&p->parmsp[3]), userp, &req,
tidPathp, scp->fid.vnode, shortName,
- &len);
+ (size_t *) &len);
if (code) {
goto done;
}
/* prepare for setattr call */
attr.mask = 0;
+
lastMod = *((FILETIME *)(p->datap + 16));
- if (LargeIntegerNotEqualToZero(*((LARGE_INTEGER *)&lastMod))) {
+ /* 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)
char shortName[13]; /* 8.3 name if needed */
int NeedShortName;
char *shortNameEnd;
+ int fileType;
+ cm_fid_t fid;
cm_req_t req;
|| (NeedShortName
&& smb_V3MatchMask(shortName, maskp,
CM_FLAG_CASEFOLD)))) {
+
+ /* Eliminate entries that don't match requested
+ attributes */
+ if (!(dsp->attribute & 0x10)) /* 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 */
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)
* we're supposed to close the search if we're done, and we're done,
* or if something went wrong, close the search.
*/
- if ((searchFlags & 1) || ((searchFlags & 2) && eos)
+ /* ((searchFlags & 1) || ((searchFlags & 2) && eos) */
+ if ((searchFlags & 1) || (returnedNames == 0)
|| code != 0) smb_DeleteDirSearch(dsp);
if (code)
smb_SendTran2Error(vcp, p, opx, code);
/* set the packet data length the count of the # of bytes */
smb_SetSMBDataLength(outp, count);
+#ifndef DJGPP
code = smb_ReadData(fidp, &offset, count, op, userp, &finalCount);
+#else /* DJGPP */
+ code = smb_ReadData(fidp, &offset, count, op, userp, &finalCount, FALSE);
+#endif /* !DJGPP */
/* fix some things up */
smb_SetSMBParm(outp, 5, finalCount);
{
lock_InitializeMutex(&smb_Dir_Watch_Lock, "Directory Watch List Lock");
}
+
+cm_user_t *smb_FindCMUserByName(/*smb_vc_t *vcp,*/ char *usern, char *machine)
+{
+ cm_user_t *userp;
+ /*int newUid;*/
+ smb_username_t *unp;
+
+ unp = smb_FindUserByName(usern, machine, SMB_FLAG_CREATE);
+ if (!unp->userp) {
+ 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);
+ } else {
+ osi_LogEvent("AFS smb_FindCMUserByName Found",NULL,"name[%s] machine[%s]",usern,machine);
+ }
+ return unp->userp;
+}
+