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.
#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__ */
* 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
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)
*pathNamep = strdup(p);
return 1;
}
- else /* create \\<netbiosName>\<cellname> */
+ 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 \\<netbiosName>\<cellname> */
if ( *p == '.' ) {
p++;
rw = 1;
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);
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);
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);
/* 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
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);
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);
*/
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);
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);
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,
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);
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);
}
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$");
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)
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,
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
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);
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);
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);
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);
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);
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) {
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) {