From: Asanka Herath Date: Tue, 27 Jul 2004 00:22:20 +0000 (+0000) Subject: afsd-20040726 X-Git-Tag: openafs-devel-1_3_66~2 X-Git-Url: https://git.openafs.org/?p=openafs.git;a=commitdiff_plain;h=92076d87491618f3194da528d8d824d3888dad95 afsd-20040726 Prevent a TID allocated for IPC from being used for anything other than RAP. Implement NetServerGetInfo instead of returning an error. When looking for shares, go through root.afs first before trying to add a mount point. --- diff --git a/src/WINNT/afsd/cm.h b/src/WINNT/afsd/cm.h index 8f3d53a..b0cef02 100644 --- a/src/WINNT/afsd/cm.h +++ b/src/WINNT/afsd/cm.h @@ -248,4 +248,5 @@ int RXAFS_Lookup (struct rx_connection *, #define CM_ERROR_AMBIGUOUS_FILENAME (CM_ERROR_BASE+41) #define CM_ERROR_BADLOGONTYPE (CM_ERROR_BASE+42) #define CM_ERROR_GSSCONTINUE (CM_ERROR_BASE+43) +#define CM_ERROR_TIDIPC (CM_ERROR_BASE+44) #endif /* __CM_H_ENV__ */ diff --git a/src/WINNT/afsd/smb.c b/src/WINNT/afsd/smb.c index 4c86898..0809864 100644 --- a/src/WINNT/afsd/smb.c +++ b/src/WINNT/afsd/smb.c @@ -1025,17 +1025,23 @@ cm_user_t *smb_GetUser(smb_vc_t *vcp, smb_packet_t *inp) * Return a pointer to a pathname extracted from a TID structure. The * TID structure is not held; assume it won't go away. */ -char *smb_GetTIDPath(smb_vc_t *vcp, unsigned short tid) +long smb_LookupTIDPath(smb_vc_t *vcp, unsigned short tid, char ** treepath) { smb_tid_t *tidp; - char *tpath; + long code = 0; tidp = smb_FindTID(vcp, tid, 0); - if (!tidp) - return NULL; - tpath = tidp->pathname; + if (!tidp) { + *treepath = NULL; + } else { + if(tidp->flags & SMB_TIDFLAG_IPC) { + code = CM_ERROR_TIDIPC; + /* tidp->pathname would be NULL, but that's fine */ + } + *treepath = tidp->pathname; smb_ReleaseTID(tidp); - return tpath; + } + return code; } /* check to see if we have a chained fid, that is, a fid that comes from an @@ -1263,6 +1269,37 @@ int smb_ListShares() return num_shares; } #endif /* DJGPP */ + +typedef struct smb_findShare_rock { + char * shareName; + char * match; + int matchType; +} smb_findShare_rock_t; + +#define SMB_FINDSHARE_EXACT_MATCH 1 +#define SMB_FINDSHARE_PARTIAL_MATCH 2 + +long smb_FindShareProc(cm_scache_t *scp, cm_dirEntry_t *dep, void *rockp, + osi_hyper_t *offp) +{ + int matchType = 0; + smb_findShare_rock_t * vrock = (smb_findShare_rock_t *) rockp; + if(!strnicmp(dep->name, vrock->shareName, 12)) { + if(!stricmp(dep->name, vrock->shareName)) + matchType = SMB_FINDSHARE_EXACT_MATCH; + else + matchType = SMB_FINDSHARE_PARTIAL_MATCH; + if(vrock->match) free(vrock->match); + vrock->match = strdup(dep->name); + vrock->matchType = matchType; + + if(matchType == SMB_FINDSHARE_EXACT_MATCH) + return CM_ERROR_STOPNOW; + } + return 0; +} + + /* find a shareName in the table of submounts */ int smb_FindShare(smb_vc_t *vcp, smb_user_t *uidp, char *shareName, char **pathNamep) @@ -1386,11 +1423,40 @@ int smb_FindShare(smb_vc_t *vcp, smb_user_t *uidp, char *shareName, *pathNamep = strdup(p); return 1; } - else /* create \\\ */ + else { + /* First lookup shareName in root.afs */ + cm_req_t req; + smb_findShare_rock_t vrock; + osi_hyper_t thyper; char * p = shareName; int rw = 0; + /* attempt to locate a partial match in root.afs. This is because + when using the ANSI RAP calls, the share name is limited to 13 chars + and hence is truncated. Of course we prefer exact matches. */ + cm_InitReq(&req); + thyper.HighPart = 0; + thyper.LowPart = 0; + + vrock.shareName = shareName; + vrock.match = NULL; + vrock.matchType = 0; + + cm_HoldSCache(cm_rootSCachep); + code = cm_ApplyDir(cm_rootSCachep, smb_FindShareProc, &vrock, &thyper, + (uidp? (uidp->unp ? uidp->unp->userp : NULL) : NULL), &req, NULL); + cm_ReleaseSCache(cm_rootSCachep); + + if(vrock.matchType) { + sprintf(pathName,"/%s/",vrock.match); + *pathNamep = strdup(strlwr(pathName)); + free(vrock.match); + return 1; + } + + /* if we get here, there was no match for the share in root.afs */ + /* so try to create \\\ */ if ( *p == '.' ) { p++; rw = 1; @@ -3298,7 +3364,14 @@ long smb_ReceiveCoreSearchDir(smb_vc_t *vcp, smb_packet_t *inp, smb_packet_t *ou spacep = inp->spacep; smb_StripLastComponent(spacep->data, NULL, pathp); lock_ReleaseMutex(&dsp->mx); - tidPathp = smb_GetTIDPath(vcp, ((smb_t *)inp)->tid); + code = smb_LookupTIDPath(vcp, ((smb_t *)inp)->tid, &tidPathp); + if(code) { + lock_ReleaseMutex(&dsp->mx); + cm_ReleaseUser(userp); + smb_DeleteDirSearch(dsp); + smb_ReleaseDirSearch(dsp); + return CM_ERROR_NOFILES; + } code = cm_NameI(cm_rootSCachep, spacep->data, caseFold | CM_FLAG_FOLLOW, userp, tidPathp, &req, &scp); lock_ObtainMutex(&dsp->mx); @@ -3675,7 +3748,11 @@ long smb_ReceiveCoreCheckPath(smb_vc_t *vcp, smb_packet_t *inp, smb_packet_t *ou caseFold = CM_FLAG_CASEFOLD; - tidPathp = smb_GetTIDPath(vcp, ((smb_t *)inp)->tid); + code = smb_LookupTIDPath(vcp, ((smb_t *)inp)->tid, &tidPathp); + if(code) { + cm_ReleaseUser(userp); + return CM_ERROR_NOSUCHPATH; + } code = cm_NameI(rootScp, pathp, caseFold | CM_FLAG_FOLLOW | CM_FLAG_CHECKPATH, userp, tidPathp, &req, &newScp); @@ -3744,7 +3821,11 @@ long smb_ReceiveCoreSetFileAttributes(smb_vc_t *vcp, smb_packet_t *inp, smb_pack caseFold = CM_FLAG_CASEFOLD; - tidPathp = smb_GetTIDPath(vcp, ((smb_t *)inp)->tid); + code = smb_LookupTIDPath(vcp, ((smb_t *)inp)->tid, &tidPathp); + if(code) { + cm_ReleaseUser(userp); + return CM_ERROR_NOSUCHFILE; + } code = cm_NameI(rootScp, pathp, caseFold | CM_FLAG_FOLLOW, userp, tidPathp, &req, &newScp); @@ -3842,7 +3923,11 @@ long smb_ReceiveCoreGetFileAttributes(smb_vc_t *vcp, smb_packet_t *inp, smb_pack /* we shouldn't need this for V3 requests, but we seem to */ caseFold = CM_FLAG_CASEFOLD; - tidPathp = smb_GetTIDPath(vcp, ((smb_t *)inp)->tid); + code = smb_LookupTIDPath(vcp, ((smb_t *)inp)->tid, &tidPathp); + if(code) { + cm_ReleaseUser(userp); + return CM_ERROR_NOSUCHFILE; + } /* * XXX Strange hack XXX @@ -4020,7 +4105,11 @@ long smb_ReceiveCoreOpen(smb_vc_t *vcp, smb_packet_t *inp, smb_packet_t *outp) caseFold = CM_FLAG_CASEFOLD; - tidPathp = smb_GetTIDPath(vcp, ((smb_t *)inp)->tid); + code = smb_LookupTIDPath(vcp, ((smb_t *)inp)->tid, &tidPathp); + if(code) { + cm_ReleaseUser(userp); + return CM_ERROR_NOSUCHPATH; + } code = cm_NameI(cm_rootSCachep, pathp, caseFold | CM_FLAG_FOLLOW, userp, tidPathp, &req, &scp); @@ -4170,7 +4259,11 @@ long smb_ReceiveCoreUnlink(smb_vc_t *vcp, smb_packet_t *inp, smb_packet_t *outp) caseFold = CM_FLAG_FOLLOW | CM_FLAG_CASEFOLD; - tidPathp = smb_GetTIDPath(vcp, ((smb_t *)inp)->tid); + code = smb_LookupTIDPath(vcp, ((smb_t *)inp)->tid, &tidPathp); + if(code) { + cm_ReleaseUser(userp); + return CM_ERROR_NOSUCHPATH; + } code = cm_NameI(cm_rootSCachep, spacep->data, caseFold, userp, tidPathp, &req, &dscp); @@ -4320,7 +4413,11 @@ long smb_ReceiveCoreRename(smb_vc_t *vcp, smb_packet_t *inp, smb_packet_t *outp) */ caseFold = CM_FLAG_FOLLOW | CM_FLAG_CASEFOLD; - tidPathp = smb_GetTIDPath(vcp, ((smb_t *)inp)->tid); + code = smb_LookupTIDPath(vcp, ((smb_t *)inp)->tid, &tidPathp); + if(code) { + cm_ReleaseUser(userp); + return CM_ERROR_NOSUCHPATH; + } code = cm_NameI(cm_rootSCachep, spacep->data, caseFold, userp, tidPathp, &req, &oldDscp); @@ -4519,7 +4616,11 @@ long smb_ReceiveCoreRemoveDir(smb_vc_t *vcp, smb_packet_t *inp, smb_packet_t *ou caseFold = CM_FLAG_CASEFOLD; - tidPathp = smb_GetTIDPath(vcp, ((smb_t *)inp)->tid); + code = smb_LookupTIDPath(vcp, ((smb_t *)inp)->tid, &tidPathp); + if(code) { + cm_ReleaseUser(userp); + return CM_ERROR_NOSUCHPATH; + } code = cm_NameI(cm_rootSCachep, spacep->data, caseFold | CM_FLAG_FOLLOW, userp, tidPathp, &req, &dscp); @@ -5522,7 +5623,11 @@ long smb_ReceiveCoreMakeDir(smb_vc_t *vcp, smb_packet_t *inp, smb_packet_t *outp caseFold = CM_FLAG_CASEFOLD; - tidPathp = smb_GetTIDPath(vcp, ((smb_t *)inp)->tid); + code = smb_LookupTIDPath(vcp, ((smb_t *)inp)->tid, &tidPathp); + if(code) { + cm_ReleaseUser(userp); + return CM_ERROR_NOSUCHPATH; + } code = cm_NameI(cm_rootSCachep, spacep->data, caseFold | CM_FLAG_FOLLOW | CM_FLAG_CHECKPATH, @@ -5629,7 +5734,11 @@ long smb_ReceiveCoreCreate(smb_vc_t *vcp, smb_packet_t *inp, smb_packet_t *outp) caseFold = CM_FLAG_CASEFOLD; - tidPathp = smb_GetTIDPath(vcp, ((smb_t *)inp)->tid); + code = smb_LookupTIDPath(vcp, ((smb_t *)inp)->tid, &tidPathp); + if(code) { + cm_ReleaseUser(userp); + return CM_ERROR_NOSUCHPATH; + } code = cm_NameI(cm_rootSCachep, spacep->data, caseFold | CM_FLAG_FOLLOW, userp, tidPathp, &req, &dscp); diff --git a/src/WINNT/afsd/smb.h b/src/WINNT/afsd/smb.h index 2144003..904b146 100644 --- a/src/WINNT/afsd/smb.h +++ b/src/WINNT/afsd/smb.h @@ -412,7 +412,7 @@ extern void smb_ReleaseUID(smb_user_t *uidp); extern cm_user_t *smb_GetUser(smb_vc_t *vcp, smb_packet_t *inp); -extern char *smb_GetTIDPath(smb_vc_t *vcp, unsigned short tid); +extern long smb_LookupTIDPath(smb_vc_t *vcp, unsigned short tid, char ** tidPathp); extern smb_fid_t *smb_FindFID(smb_vc_t *vcp, unsigned short fid, int flags); diff --git a/src/WINNT/afsd/smb3.c b/src/WINNT/afsd/smb3.c index 54b578f..0963f75 100644 --- a/src/WINNT/afsd/smb3.c +++ b/src/WINNT/afsd/smb3.c @@ -940,6 +940,10 @@ long smb_ReceiveV3TreeConnectX(smb_vc_t *vcp, smb_packet_t *inp, smb_packet_t *o } strcpy(shareName, tp+1); + osi_Log2(smb_logp, "Tree connect pathp[%s] shareName[%s]", + osi_LogSaveString(smb_logp, pathp), + osi_LogSaveString(smb_logp, shareName)); + if (strcmp(servicep, "IPC") == 0 || strcmp(shareName, "IPC$") == 0) { #ifndef NO_IPC osi_Log0(smb_logp, "TreeConnectX connecting to IPC$"); @@ -1756,9 +1760,92 @@ long smb_ReceiveRAPNetWkstaGetInfo(smb_vc_t *vcp, smb_tran2Packet_t *p, smb_pack return code; } +typedef struct smb_rap_server_info_0 { + char sv0_name[16]; +} smb_rap_server_info_0_t; + +typedef struct smb_rap_server_info_1 { + char sv1_name[16]; + char sv1_version_major; + char sv1_version_minor; + unsigned long sv1_type; + DWORD *sv1_comment_or_master_browser; /* char *sv1_comment_or_master_browser;*/ +} smb_rap_server_info_1_t; + +char smb_ServerComment[] = "OpenAFS Client"; +int smb_ServerCommentLen = sizeof(smb_ServerComment); + +#define SMB_SV_TYPE_SERVER 0x00000002L +#define SMB_SV_TYPE_NT 0x00001000L +#define SMB_SV_TYPE_SERVER_NT 0x00008000L + long smb_ReceiveRAPNetServerGetInfo(smb_vc_t *vcp, smb_tran2Packet_t *p, smb_packet_t *op) { - return CM_ERROR_BADOP; + smb_tran2Packet_t *outp; + long code = 0; + int infoLevel; + int bufsize; + unsigned short * tp; + int totalData; + int totalParams; + smb_rap_server_info_0_t * info0; + smb_rap_server_info_1_t * info1; + char * cstrp; + + tp = p->parmsp + 1; /* Skip over function number */ + (void) smb_ParseString((unsigned char*) tp, (char **) &tp); /* skip over param descriptor */ + (void) smb_ParseString((unsigned char*) tp, (char **) &tp); /* skip over data descriptor */ + infoLevel = *tp++; + bufsize = *tp++; + + if(infoLevel != 0 && infoLevel != 1) { + return CM_ERROR_INVAL; + } + + totalParams = 6; + + totalData = + (infoLevel == 0) ? sizeof(smb_rap_server_info_0_t) + : (sizeof(smb_rap_server_info_1_t) + smb_ServerCommentLen); + + outp = smb_GetTran2ResponsePacket(vcp, p, op, totalParams, totalData); + + memset(outp->parmsp,0,totalParams); + memset(outp->datap,0,totalData); + + if(infoLevel == 0) { + info0 = (smb_rap_share_info_0_t *) outp->datap; + cstrp = (char *) (info0 + 1); + strcpy(info0->sv0_name, "AFS"); + } else { /* infoLevel == 1 */ + info1 = (smb_rap_share_info_1_t *) outp->datap; + cstrp = (char *) (info1 + 1); + strcpy(info1->sv1_name, "AFS"); + + info1->sv1_type = + SMB_SV_TYPE_SERVER | + SMB_SV_TYPE_NT | + SMB_SV_TYPE_SERVER_NT; + + info1->sv1_version_major = 5; + info1->sv1_version_minor = 1; + info1->sv1_comment_or_master_browser = (DWORD) (cstrp - outp->datap); + + strcpy(cstrp, smb_ServerComment); + + cstrp += smb_ServerCommentLen; + } + + totalData = cstrp - outp->datap; + outp->totalData = min(bufsize,totalData); /* actual data size */ + outp->parmsp[0] = (outp->totalData == totalData)? 0 : ERROR_MORE_DATA; + outp->parmsp[2] = totalData; + outp->totalParms = totalParams; + + smb_SendTran2Packet(vcp,outp,op); + smb_FreeTran2Packet(outp); + + return code; } long smb_ReceiveV3Tran2A(smb_vc_t *vcp, smb_packet_t *inp, smb_packet_t *outp) @@ -2006,7 +2093,16 @@ long smb_ReceiveTran2Open(smb_vc_t *vcp, smb_tran2Packet_t *p, smb_packet_t *op) return CM_ERROR_BADSMB; } - tidPathp = smb_GetTIDPath(vcp, p->tid); + code = smb_LookupTIDPath(vcp, p->tid, &tidPathp); + if(code == CM_ERROR_TIDIPC) { + /* Attempt to use TID allocated for IPC. The client is + probably trying to locate DCE RPC end points, which + we don't support. */ + osi_Log0(smb_logp, "Tran2Open received IPC TID"); + cm_ReleaseUser(userp); + smb_FreeTran2Packet(outp); + return CM_ERROR_NOSUCHPATH; + } dscp = NULL; code = cm_NameI(cm_rootSCachep, pathp, @@ -2429,7 +2525,13 @@ long smb_ReceiveTran2QPathInfo(smb_vc_t *vcp, smb_tran2Packet_t *p, smb_packet_t return CM_ERROR_BADSMB; } - tidPathp = smb_GetTIDPath(vcp, p->tid); + code = smb_LookupTIDPath(vcp, p->tid, &tidPathp); + if(code) { + cm_ReleaseUser(userp); + smb_SendTran2Error(vcp, p, opx, CM_ERROR_NOSUCHPATH); + smb_FreeTran2Packet(outp); + return 0; + } /* * XXX Strange hack XXX @@ -3368,7 +3470,15 @@ long smb_ReceiveTran2SearchDir(smb_vc_t *vcp, smb_tran2Packet_t *p, smb_packet_t smb_StripLastComponent(spacep->data, NULL, pathp); lock_ReleaseMutex(&dsp->mx); - tidPathp = smb_GetTIDPath(vcp, p->tid); + code = smb_LookupTIDPath(vcp, p->tid, &tidPathp); + if(code) { + cm_ReleaseUser(userp); + smb_SendTran2Error(vcp, p, opx, CM_ERROR_NOFILES); + smb_FreeTran2Packet(outp); + smb_DeleteDirSearch(dsp); + smb_ReleaseDirSearch(dsp); + return 0; + } code = cm_NameI(cm_rootSCachep, spacep->data, CM_FLAG_FOLLOW | CM_FLAG_CASEFOLD, userp, tidPathp, &req, &scp); @@ -3958,7 +4068,11 @@ long smb_ReceiveV3OpenX(smb_vc_t *vcp, smb_packet_t *inp, smb_packet_t *outp) userp = smb_GetUser(vcp, inp); dscp = NULL; - tidPathp = smb_GetTIDPath(vcp, ((smb_t *)inp)->tid); + code = smb_LookupTIDPath(vcp, ((smb_t *)inp)->tid, &tidPathp); + if(code) { + cm_ReleaseUser(userp); + return CM_ERROR_NOSUCHPATH; + } code = cm_NameI(cm_rootSCachep, pathp, CM_FLAG_FOLLOW | CM_FLAG_CASEFOLD, userp, tidPathp, &req, &scp); @@ -4603,7 +4717,16 @@ long smb_ReceiveNTCreateX(smb_vc_t *vcp, smb_packet_t *inp, smb_packet_t *outp) if (baseFid == 0) { baseDirp = cm_rootSCachep; - tidPathp = smb_GetTIDPath(vcp, ((smb_t *)inp)->tid); + code = smb_LookupTIDPath(vcp, ((smb_t *)inp)->tid, &tidPathp); + if(code == CM_ERROR_TIDIPC) { + /* Attempt to use a TID allocated for IPC. The client + is probably looking for DCE RPC end points which we + don't support. */ + osi_Log0(smb_logp, "NTCreateX received IPC TID"); + free(realPathp); + cm_ReleaseUser(userp); + return CM_ERROR_NOSUCHFILE; + } } else { baseFidp = smb_FindFID(vcp, baseFid, 0); @@ -5118,7 +5241,16 @@ long smb_ReceiveNTTranCreate(smb_vc_t *vcp, smb_packet_t *inp, smb_packet_t *out if (baseFid == 0) { baseDirp = cm_rootSCachep; - tidPathp = smb_GetTIDPath(vcp, ((smb_t *)inp)->tid); + code = smb_LookupTIDPath(vcp, ((smb_t *)inp)->tid, &tidPathp); + if(code == CM_ERROR_TIDIPC) { + /* Attempt to use TID allocated for IPC. The client is + probably trying to locate DCE RPC endpoints, which we + don't support. */ + osi_Log0(smb_logp, "NTTranCreate received IPC TID"); + free(realPathp); + cm_ReleaseUser(userp); + return CM_ERROR_NOSUCHPATH; + } } else { baseFidp = smb_FindFID(vcp, baseFid, 0); diff --git a/src/WINNT/afsd/smb_ioctl.c b/src/WINNT/afsd/smb_ioctl.c index 32d2beb..c35849d 100644 --- a/src/WINNT/afsd/smb_ioctl.c +++ b/src/WINNT/afsd/smb_ioctl.c @@ -181,7 +181,11 @@ long smb_IoctlRead(smb_fid_t *fidp, smb_vc_t *vcp, smb_packet_t *inp, userp = smb_GetUser(vcp, inp); /* Identify tree */ - iop->tidPathp = smb_GetTIDPath(vcp, ((smb_t *)inp)->tid); + code = smb_LookupTIDPath(vcp, ((smb_t *)inp)->tid, &iop->tidPathp); + if(code) { + cm_ReleaseUser(userp); + return CM_ERROR_NOSUCHPATH; + } /* turn the connection around, if required */ code = smb_IoctlPrepareRead(fidp, iop, userp); @@ -294,7 +298,13 @@ long smb_IoctlV3Read(smb_fid_t *fidp, smb_vc_t *vcp, smb_packet_t *inp, smb_pack userp); } - iop->tidPathp = smb_GetTIDPath(vcp, ((smb_t *)inp)->tid); + code = smb_LookupTIDPath(vcp, ((smb_t *)inp)->tid, &iop->tidPathp); + if(code) { + smb_ReleaseUID(uidp); + cm_ReleaseUser(userp); + smb_ReleaseFID(fidp); + return CM_ERROR_NOSUCHPATH; + } code = smb_IoctlPrepareRead(fidp, iop, userp); if (uidp) { @@ -392,7 +402,12 @@ long smb_IoctlReadRaw(smb_fid_t *fidp, smb_vc_t *vcp, smb_packet_t *inp, if (uidp) smb_ReleaseUID(uidp); } - iop->tidPathp = smb_GetTIDPath(vcp, ((smb_t *)inp)->tid); + code = smb_LookupTIDPath(vcp, ((smb_t *)inp)->tid, &iop->tidPathp); + if(code) { + cm_ReleaseUser(userp); + smb_ReleaseFID(fidp); + return CM_ERROR_NOSUCHPATH; + } code = smb_IoctlPrepareRead(fidp, iop, userp); if (code) {