* directory or online at http://www.openafs.org/dl/license10.html
*/
-//#define NOSERVICE 1
+//#define NOTSERVICE 1
+#define LOG_PACKET 1
#include <afs/param.h>
#include <afs/stds.h>
*(sizep) = strlen(cm_HostName)
#endif /* DJGPP */
+#ifdef LOG_PACKET
+void smb_LogPacket(smb_packet_t *packet);
+#endif /* LOG_PACKET */
extern char AFSConfigKeyName[];
char smb_ServerDomainName[MAX_COMPUTERNAME_LENGTH + 1] = ""; /* domain name */
char * myCrt_Dispatch(int i)
{
- switch (i)
- {
- default:
- return "unknown SMB op";
- case 0x00:
- return "(00)ReceiveCoreMakeDir";
- case 0x01:
- return "(01)ReceiveCoreRemoveDir";
- case 0x02:
- return "(02)ReceiveCoreOpen";
- case 0x03:
- return "(03)ReceiveCoreCreate";
- case 0x04:
- return "(04)ReceiveCoreClose";
- case 0x05:
- return "(05)ReceiveCoreFlush";
- case 0x06:
- return "(06)ReceiveCoreUnlink";
- case 0x07:
- return "(07)ReceiveCoreRename";
- case 0x08:
- return "(08)ReceiveCoreGetFileAttributes";
- case 0x09:
- return "(09)ReceiveCoreSetFileAttributes";
- case 0x0a:
- return "(0a)ReceiveCoreRead";
- case 0x0b:
- return "(0b)ReceiveCoreWrite";
- case 0x0c:
- return "(0c)ReceiveCoreLockRecord";
- case 0x0d:
- return "(0d)ReceiveCoreUnlockRecord";
- case 0x0e:
- return "(0e)SendCoreBadOp";
- case 0x0f:
- return "(0f)ReceiveCoreCreate";
- case 0x10:
- return "(10)ReceiveCoreCheckPath";
- case 0x11:
- return "(11)SendCoreBadOp";
- case 0x12:
- return "(12)ReceiveCoreSeek";
- case 0x1a:
- return "(1a)ReceiveCoreReadRaw";
- case 0x1d:
- return "(1d)ReceiveCoreWriteRawDummy";
- case 0x22:
- return "(22)ReceiveV3SetAttributes";
- case 0x23:
- return "(23)ReceiveV3GetAttributes";
- case 0x24:
- return "(24)ReceiveV3LockingX";
- case 0x25:
- return "(25)ReceiveV3Trans";
- case 0x26:
- return "(26)ReceiveV3Trans[aux]";
- case 0x29:
- return "(29)SendCoreBadOp";
- case 0x2b:
- return "(2b)ReceiveCoreEcho";
- case 0x2d:
- return "(2d)ReceiveV3OpenX";
- case 0x2e:
- return "(2e)ReceiveV3ReadX";
- case 0x32:
- return "(32)ReceiveV3Tran2A";
- case 0x33:
- return "(33)ReceiveV3Tran2A[aux]";
- case 0x34:
- return "(34)ReceiveV3FindClose";
- case 0x35:
- return "(35)ReceiveV3FindNotifyClose";
- case 0x70:
- return "(70)ReceiveCoreTreeConnect";
- case 0x71:
- return "(71)ReceiveCoreTreeDisconnect";
- case 0x72:
- return "(72)ReceiveNegotiate";
- case 0x73:
- return "(73)ReceiveV3SessionSetupX";
- case 0x74:
- return "(74)ReceiveV3UserLogoffX";
- case 0x75:
- return "(75)ReceiveV3TreeConnectX";
- case 0x80:
- return "(80)ReceiveCoreGetDiskAttributes";
- case 0x81:
- return "(81)ReceiveCoreSearchDir";
- case 0xA0:
- return "(A0)ReceiveNTTransact";
- case 0xA2:
- return "(A2)ReceiveNTCreateX";
- case 0xA4:
- return "(A4)ReceiveNTCancel";
- case 0xc0:
- return "(c0)SendCoreBadOp";
- case 0xc1:
- return "(c1)SendCoreBadOp";
- case 0xc2:
- return "(c2)SendCoreBadOp";
- case 0xc3:
- return "(c3)SendCoreBadOp";
- }
-}
+ switch (i)
+ {
+ case 0x00:
+ return "(00)ReceiveCoreMakeDir";
+ case 0x01:
+ return "(01)ReceiveCoreRemoveDir";
+ case 0x02:
+ return "(02)ReceiveCoreOpen";
+ case 0x03:
+ return "(03)ReceiveCoreCreate";
+ case 0x04:
+ return "(04)ReceiveCoreClose";
+ case 0x05:
+ return "(05)ReceiveCoreFlush";
+ case 0x06:
+ return "(06)ReceiveCoreUnlink";
+ case 0x07:
+ return "(07)ReceiveCoreRename";
+ case 0x08:
+ return "(08)ReceiveCoreGetFileAttributes";
+ case 0x09:
+ return "(09)ReceiveCoreSetFileAttributes";
+ case 0x0a:
+ return "(0a)ReceiveCoreRead";
+ case 0x0b:
+ return "(0b)ReceiveCoreWrite";
+ case 0x0c:
+ return "(0c)ReceiveCoreLockRecord";
+ case 0x0d:
+ return "(0d)ReceiveCoreUnlockRecord";
+ case 0x0e:
+ return "(0e)SendCoreBadOp";
+ case 0x0f:
+ return "(0f)ReceiveCoreCreate";
+ case 0x10:
+ return "(10)ReceiveCoreCheckPath";
+ case 0x11:
+ return "(11)SendCoreBadOp";
+ case 0x12:
+ return "(12)ReceiveCoreSeek";
+ case 0x1a:
+ return "(1a)ReceiveCoreReadRaw";
+ case 0x1d:
+ return "(1d)ReceiveCoreWriteRawDummy";
+ case 0x22:
+ return "(22)ReceiveV3SetAttributes";
+ case 0x23:
+ return "(23)ReceiveV3GetAttributes";
+ case 0x24:
+ return "(24)ReceiveV3LockingX";
+ case 0x25:
+ return "(25)ReceiveV3Trans";
+ case 0x26:
+ return "(26)ReceiveV3Trans[aux]";
+ case 0x29:
+ return "(29)SendCoreBadOp";
+ case 0x2b:
+ return "(2b)ReceiveCoreEcho";
+ case 0x2d:
+ return "(2d)ReceiveV3OpenX";
+ case 0x2e:
+ return "(2e)ReceiveV3ReadX";
+ case 0x32:
+ return "(32)ReceiveV3Tran2A";
+ case 0x33:
+ return "(33)ReceiveV3Tran2A[aux]";
+ case 0x34:
+ return "(34)ReceiveV3FindClose";
+ case 0x35:
+ return "(35)ReceiveV3FindNotifyClose";
+ case 0x70:
+ return "(70)ReceiveCoreTreeConnect";
+ case 0x71:
+ return "(71)ReceiveCoreTreeDisconnect";
+ case 0x72:
+ return "(72)ReceiveNegotiate";
+ case 0x73:
+ return "(73)ReceiveV3SessionSetupX";
+ case 0x74:
+ return "(74)ReceiveV3UserLogoffX";
+ case 0x75:
+ return "(75)ReceiveV3TreeConnectX";
+ case 0x80:
+ return "(80)ReceiveCoreGetDiskAttributes";
+ case 0x81:
+ return "(81)ReceiveCoreSearchDir";
+ case 0x82:
+ return "(82)Find";
+ case 0x83:
+ return "(83)FindUnique";
+ case 0x84:
+ return "(84)FindClose";
+ case 0xA0:
+ return "(A0)ReceiveNTTransact";
+ case 0xA2:
+ return "(A2)ReceiveNTCreateX";
+ case 0xA4:
+ return "(A4)ReceiveNTCancel";
+ case 0xA5:
+ return "(A5)ReceiveNTRename";
+ case 0xc0:
+ return "(C0)OpenPrintFile";
+ case 0xc1:
+ return "(C1)WritePrintFile";
+ case 0xc2:
+ return "(C2)ClosePrintFile";
+ case 0xc3:
+ return "(C3)GetPrintQueue";
+ case 0xd8:
+ return "(D8)ReadBulk";
+ case 0xd9:
+ return "(D9)WriteBulk";
+ case 0xda:
+ return "(DA)WriteBulkData";
+ default:
+ return "unknown SMB op";
+ }
+}
char * myCrt_2Dispatch(int i)
{
- switch (i)
- {
- default:
- return "unknown SMB op-2";
- case 0:
- return "S(00)CreateFile";
- case 1:
- return "S(01)FindFirst";
- case 2:
- return "S(02)FindNext"; /* FindNext */
- case 3:
- return "S(03)QueryFileSystem_ReceiveTran2QFSInfo";
- case 4:
- return "S(04)??";
- case 5:
- return "S(05)QueryFileInfo_ReceiveTran2QPathInfo";
- case 6:
- return "S(06)SetFileInfo_ReceiveTran2SetPathInfo";
- case 7:
- return "S(07)SetInfoHandle_ReceiveTran2QFileInfo";
- case 8:
- return "S(08)??_ReceiveTran2SetFileInfo";
- case 9:
- return "S(09)??_ReceiveTran2FSCTL";
- case 10:
- return "S(0a)_ReceiveTran2IOCTL";
- case 11:
- return "S(0b)_ReceiveTran2FindNotifyFirst";
- case 12:
- return "S(0c)_ReceiveTran2FindNotifyNext";
- case 13:
- return "S(0d)CreateDirectory_ReceiveTran2MKDir";
- }
-}
+ switch (i)
+ {
+ default:
+ return "unknown SMB op-2";
+ case 0:
+ return "S(00)CreateFile";
+ case 1:
+ return "S(01)FindFirst";
+ case 2:
+ return "S(02)FindNext"; /* FindNext */
+ case 3:
+ return "S(03)QueryFileSystem_ReceiveTran2QFSInfo";
+ case 4:
+ return "S(04)??";
+ case 5:
+ return "S(05)QueryFileInfo_ReceiveTran2QPathInfo";
+ case 6:
+ return "S(06)SetFileInfo_ReceiveTran2SetPathInfo";
+ case 7:
+ return "S(07)SetInfoHandle_ReceiveTran2QFileInfo";
+ case 8:
+ return "S(08)??_ReceiveTran2SetFileInfo";
+ case 9:
+ return "S(09)??_ReceiveTran2FSCTL";
+ case 10:
+ return "S(0a)_ReceiveTran2IOCTL";
+ case 11:
+ return "S(0b)_ReceiveTran2FindNotifyFirst";
+ case 12:
+ return "S(0c)_ReceiveTran2FindNotifyNext";
+ case 13:
+ return "S(0d)_ReceiveTran2CreateDirectory";
+ case 14:
+ return "S(0e)_ReceiveTran2SessionSetup";
+ }
+}
char * myCrt_RapDispatch(int i)
{
- switch(i)
- {
- default:
- return "unknown RAP OP";
- case 0:
- return "RAP(0)NetShareEnum";
- case 1:
- return "RAP(1)NetShareGetInfo";
- case 13:
- return "RAP(13)NetServerGetInfo";
- case 63:
- return "RAP(63)NetWkStaGetInfo";
- }
-}
+ switch(i)
+ {
+ default:
+ return "unknown RAP OP";
+ case 0:
+ return "RAP(0)NetShareEnum";
+ case 1:
+ return "RAP(1)NetShareGetInfo";
+ case 13:
+ return "RAP(13)NetServerGetInfo";
+ case 63:
+ return "RAP(63)NetWkStaGetInfo";
+ }
+}
/* scache must be locked */
unsigned int smb_Attributes(cm_scache_t *scp)
int smb_FindShareCSCPolicy(char *shareName)
{
- DWORD len;
- char policy[1024];
+ DWORD len;
+ char policy[1024];
DWORD dwType;
HKEY hkCSCPolicy;
int retval = CSC_POLICY_MANUAL;
len = sizeof(policy);
if ( RegQueryValueEx( hkCSCPolicy, shareName, 0, &dwType, policy, &len ) ||
len == 0) {
- retval = CSC_POLICY_MANUAL;
+ retval = stricmp("all",shareName) ? CSC_POLICY_MANUAL : CSC_POLICY_DISABLE;
+ }
+ else if (stricmp(policy, "documents") == 0)
+ {
+ retval = CSC_POLICY_DOCUMENTS;
+ }
+ else if (stricmp(policy, "programs") == 0)
+ {
+ retval = CSC_POLICY_PROGRAMS;
+ }
+ else if (stricmp(policy, "disable") == 0)
+ {
+ retval = CSC_POLICY_DISABLE;
}
- else if (stricmp(policy, "documents") == 0)
- {
- retval = CSC_POLICY_DOCUMENTS;
- }
- else if (stricmp(policy, "programs") == 0)
- {
- retval = CSC_POLICY_PROGRAMS;
- }
- else if (stricmp(policy, "disable") == 0)
- {
- retval = CSC_POLICY_DISABLE;
- }
RegCloseKey(hkCSCPolicy);
return retval;
#endif /* !DJGPP */
if (code != 0)
- osi_Log1(smb_logp, "SendPacket failure code %d", code);
+ osi_Log1(smb_logp, "SendPacket failure code %d", code);
if (localNCB)
- FreeNCB(ncbp);
+ FreeNCB(ncbp);
}
void smb_MapNTError(long code, unsigned long *NTStatusp)
{
- unsigned long NTStatus;
+ unsigned long NTStatus;
- /* map CM_ERROR_* errors to NT 32-bit status codes */
+ /* map CM_ERROR_* errors to NT 32-bit status codes */
/* NT Status codes are listed in ntstatus.h not winerror.h */
- if (code == CM_ERROR_NOSUCHCELL) {
- NTStatus = 0xC000000FL; /* No such file */
- }
- else if (code == CM_ERROR_NOSUCHVOLUME) {
- NTStatus = 0xC000000FL; /* No such file */
- }
- else if (code == CM_ERROR_TIMEDOUT) {
- NTStatus = 0xC00000CFL; /* Sharing Paused */
- }
- else if (code == CM_ERROR_RETRY) {
- NTStatus = 0xC000022DL; /* Retry */
- }
- else if (code == CM_ERROR_NOACCESS) {
- NTStatus = 0xC0000022L; /* Access denied */
- }
- else if (code == CM_ERROR_READONLY) {
- NTStatus = 0xC00000A2L; /* Write protected */
- }
- else if (code == CM_ERROR_NOSUCHFILE) {
- NTStatus = 0xC000000FL; /* No such file */
- }
- else if (code == CM_ERROR_NOSUCHPATH) {
- NTStatus = 0xC000003AL; /* Object path not found */
- }
- else if (code == CM_ERROR_TOOBIG) {
- NTStatus = 0xC000007BL; /* Invalid image format */
- }
- else if (code == CM_ERROR_INVAL) {
- NTStatus = 0xC000000DL; /* Invalid parameter */
- }
- else if (code == CM_ERROR_BADFD) {
- NTStatus = 0xC0000008L; /* Invalid handle */
- }
- else if (code == CM_ERROR_BADFDOP) {
- NTStatus = 0xC0000022L; /* Access denied */
- }
- else if (code == CM_ERROR_EXISTS) {
- NTStatus = 0xC0000035L; /* Object name collision */
- }
- else if (code == CM_ERROR_NOTEMPTY) {
- NTStatus = 0xC0000101L; /* Directory not empty */
- }
- else if (code == CM_ERROR_CROSSDEVLINK) {
- NTStatus = 0xC00000D4L; /* Not same device */
- }
- else if (code == CM_ERROR_NOTDIR) {
- NTStatus = 0xC0000103L; /* Not a directory */
- }
- else if (code == CM_ERROR_ISDIR) {
- NTStatus = 0xC00000BAL; /* File is a directory */
- }
- else if (code == CM_ERROR_BADOP) {
- NTStatus = 0xC09820FFL; /* SMB no support */
- }
- else if (code == CM_ERROR_BADSHARENAME) {
- NTStatus = 0xC00000CCL; /* Bad network name */
- }
- else if (code == CM_ERROR_NOIPC) {
+ if (code == CM_ERROR_NOSUCHCELL) {
+ NTStatus = 0xC000000FL; /* No such file */
+ }
+ else if (code == CM_ERROR_NOSUCHVOLUME) {
+ NTStatus = 0xC000000FL; /* No such file */
+ }
+ else if (code == CM_ERROR_TIMEDOUT) {
+ NTStatus = 0xC00000CFL; /* Sharing Paused */
+ }
+ else if (code == CM_ERROR_RETRY) {
+ NTStatus = 0xC000022DL; /* Retry */
+ }
+ else if (code == CM_ERROR_NOACCESS) {
+ NTStatus = 0xC0000022L; /* Access denied */
+ }
+ else if (code == CM_ERROR_READONLY) {
+ NTStatus = 0xC00000A2L; /* Write protected */
+ }
+ else if (code == CM_ERROR_NOSUCHFILE) {
+ NTStatus = 0xC000000FL; /* No such file */
+ }
+ else if (code == CM_ERROR_NOSUCHPATH) {
+ NTStatus = 0xC000003AL; /* Object path not found */
+ }
+ else if (code == CM_ERROR_TOOBIG) {
+ NTStatus = 0xC000007BL; /* Invalid image format */
+ }
+ else if (code == CM_ERROR_INVAL) {
+ NTStatus = 0xC000000DL; /* Invalid parameter */
+ }
+ else if (code == CM_ERROR_BADFD) {
+ NTStatus = 0xC0000008L; /* Invalid handle */
+ }
+ else if (code == CM_ERROR_BADFDOP) {
+ NTStatus = 0xC0000022L; /* Access denied */
+ }
+ else if (code == CM_ERROR_EXISTS) {
+ NTStatus = 0xC0000035L; /* Object name collision */
+ }
+ else if (code == CM_ERROR_NOTEMPTY) {
+ NTStatus = 0xC0000101L; /* Directory not empty */
+ }
+ else if (code == CM_ERROR_CROSSDEVLINK) {
+ NTStatus = 0xC00000D4L; /* Not same device */
+ }
+ else if (code == CM_ERROR_NOTDIR) {
+ NTStatus = 0xC0000103L; /* Not a directory */
+ }
+ else if (code == CM_ERROR_ISDIR) {
+ NTStatus = 0xC00000BAL; /* File is a directory */
+ }
+ else if (code == CM_ERROR_BADOP) {
#ifdef COMMENT
- NTStatus = 0xC0000022L; /* Access Denied */
+ /* I have no idea where this comes from */
+ NTStatus = 0xC09820FFL; /* SMB no support */
#else
+ NTStatus = 0xC00000BBL; /* Not supported */
+#endif /* COMMENT */
+ }
+ else if (code == CM_ERROR_BADSHARENAME) {
+ NTStatus = 0xC00000CCL; /* Bad network name */
+ }
+ else if (code == CM_ERROR_NOIPC) {
+#ifdef COMMENT
+ NTStatus = 0xC0000022L; /* Access Denied */
+#else
NTStatus = 0xC000013DL; /* Remote Resources */
#endif
- }
- else if (code == CM_ERROR_CLOCKSKEW) {
- NTStatus = 0xC0000133L; /* Time difference at DC */
- }
- else if (code == CM_ERROR_BADTID) {
- NTStatus = 0xC0982005L; /* SMB bad TID */
- }
- else if (code == CM_ERROR_USESTD) {
- NTStatus = 0xC09820FBL; /* SMB use standard */
- }
- else if (code == CM_ERROR_QUOTA) {
- NTStatus = 0xC0000044L; /* Quota exceeded */
- }
- else if (code == CM_ERROR_SPACE) {
- NTStatus = 0xC000007FL; /* Disk full */
- }
- else if (code == CM_ERROR_ATSYS) {
- NTStatus = 0xC0000033L; /* Object name invalid */
- }
- else if (code == CM_ERROR_BADNTFILENAME) {
- NTStatus = 0xC0000033L; /* Object name invalid */
- }
- else if (code == CM_ERROR_WOULDBLOCK) {
- NTStatus = 0xC0000055L; /* Lock not granted */
- }
- else if (code == CM_ERROR_PARTIALWRITE) {
- NTStatus = 0xC000007FL; /* Disk full */
- }
- else if (code == CM_ERROR_BUFFERTOOSMALL) {
- NTStatus = 0xC0000023L; /* Buffer too small */
- }
+ }
+ else if (code == CM_ERROR_CLOCKSKEW) {
+ NTStatus = 0xC0000133L; /* Time difference at DC */
+ }
+ else if (code == CM_ERROR_BADTID) {
+ NTStatus = 0xC0982005L; /* SMB bad TID */
+ }
+ else if (code == CM_ERROR_USESTD) {
+ NTStatus = 0xC09820FBL; /* SMB use standard */
+ }
+ else if (code == CM_ERROR_QUOTA) {
+ NTStatus = 0xC0000044L; /* Quota exceeded */
+ }
+ else if (code == CM_ERROR_SPACE) {
+ NTStatus = 0xC000007FL; /* Disk full */
+ }
+ else if (code == CM_ERROR_ATSYS) {
+ NTStatus = 0xC0000033L; /* Object name invalid */
+ }
+ else if (code == CM_ERROR_BADNTFILENAME) {
+ NTStatus = 0xC0000033L; /* Object name invalid */
+ }
+ else if (code == CM_ERROR_WOULDBLOCK) {
+ NTStatus = 0xC0000055L; /* Lock not granted */
+ }
+ else if (code == CM_ERROR_PARTIALWRITE) {
+ NTStatus = 0xC000007FL; /* Disk full */
+ }
+ else if (code == CM_ERROR_BUFFERTOOSMALL) {
+ NTStatus = 0xC0000023L; /* Buffer too small */
+ }
else if (code == CM_ERROR_AMBIGUOUS_FILENAME) {
- NTStatus = 0xC0000035L; /* Object name collision */
+ NTStatus = 0xC0000035L; /* Object name collision */
+ }
+ else if (code == CM_ERROR_BADPASSWORD) {
+ NTStatus = 0xC000006DL; /* unknown username or bad password */
+ }
+ else if (code == CM_ERROR_BADLOGONTYPE) {
+ NTStatus = 0xC000015BL; /* logon type not granted */
+ }
+ else if (code == CM_ERROR_GSSCONTINUE) {
+ NTStatus = 0xC0000016L; /* more processing required */
+ }
+ else {
+ NTStatus = 0xC0982001L; /* SMB non-specific error */
}
- else if (code == CM_ERROR_BADPASSWORD) {
- NTStatus = 0xC000006DL; /* unknown username or bad password */
- }
- else if (code == CM_ERROR_BADLOGONTYPE) {
- NTStatus = 0xC000015BL; /* logon type not granted */
- }
- else if (code == CM_ERROR_GSSCONTINUE) {
- NTStatus = 0xC0000016L; /* more processing required */
- }
- else {
- NTStatus = 0xC0982001L; /* SMB non-specific error */
- }
- *NTStatusp = NTStatus;
- osi_Log2(smb_logp, "SMB SEND code %lX as NT %lX", code, NTStatus);
-}
+ *NTStatusp = NTStatus;
+ osi_Log2(smb_logp, "SMB SEND code %lX as NT %lX", code, NTStatus);
+}
void smb_MapCoreError(long code, smb_vc_t *vcp, unsigned short *scodep,
unsigned char *classp)
long smb_SendCoreBadOp(smb_vc_t *vcp, smb_packet_t *inp, smb_packet_t *outp)
{
- return CM_ERROR_BADOP;
+ osi_Log0(smb_logp,"SendCoreBadOp - NOT_SUPPORTED");
+ return CM_ERROR_BADOP;
}
long smb_ReceiveCoreEcho(smb_vc_t *vcp, smb_packet_t *inp, smb_packet_t *outp)
return code;
}
-long smb_ReceiveCoreRename(smb_vc_t *vcp, smb_packet_t *inp, smb_packet_t *outp)
-{
- long code = 0;
- char *oldPathp;
- char *newPathp;
- char *tp;
- cm_space_t *spacep = NULL;
- smb_renameRock_t rock;
- cm_scache_t *oldDscp = NULL;
- cm_scache_t *newDscp = NULL;
- cm_scache_t *tmpscp= NULL;
- cm_scache_t *tmpscp2 = NULL;
- char *oldLastNamep;
- char *newLastNamep;
- osi_hyper_t thyper;
- cm_user_t *userp;
- int caseFold;
- char *tidPathp;
- DWORD filter;
- cm_req_t req;
-
- cm_InitReq(&req);
-
- tp = smb_GetSMBData(inp, NULL);
- oldPathp = smb_ParseASCIIBlock(tp, &tp);
- newPathp = smb_ParseASCIIBlock(tp, &tp);
- osi_Log2(smb_logp, "smb rename [%s] to [%s]",
- osi_LogSaveString(smb_logp, oldPathp),
- osi_LogSaveString(smb_logp, newPathp));
+long
+smb_Rename(smb_vc_t *vcp, smb_packet_t *inp, char * oldPathp, char * newPathp, int attrs)
+{
+ long code = 0;
+ cm_space_t *spacep = NULL;
+ smb_renameRock_t rock;
+ cm_scache_t *oldDscp = NULL;
+ cm_scache_t *newDscp = NULL;
+ cm_scache_t *tmpscp= NULL;
+ cm_scache_t *tmpscp2 = NULL;
+ char *oldLastNamep;
+ char *newLastNamep;
+ osi_hyper_t thyper;
+ cm_user_t *userp;
+ int caseFold;
+ char *tidPathp;
+ DWORD filter;
+ cm_req_t req;
- spacep = inp->spacep;
- smb_StripLastComponent(spacep->data, &oldLastNamep, oldPathp);
+ userp = smb_GetUser(vcp, inp);
+ code = smb_LookupTIDPath(vcp, ((smb_t *)inp)->tid, &tidPathp);
+ if (code) {
+ cm_ReleaseUser(userp);
+ return CM_ERROR_NOSUCHPATH;
+ }
- userp = smb_GetUser(vcp, inp);
+ cm_InitReq(&req);
+ spacep = inp->spacep;
+ smb_StripLastComponent(spacep->data, &oldLastNamep, oldPathp);
/*
* Changed to use CASEFOLD always. This enables us to rename Foo/baz when
*
* caseFold = CM_FLAG_CASEFOLD;
*/
- caseFold = CM_FLAG_FOLLOW | CM_FLAG_CASEFOLD;
+ caseFold = CM_FLAG_FOLLOW | CM_FLAG_CASEFOLD;
+ code = cm_NameI(cm_rootSCachep, spacep->data, caseFold,
+ userp, tidPathp, &req, &oldDscp);
- code = smb_LookupTIDPath(vcp, ((smb_t *)inp)->tid, &tidPathp);
- if(code) {
+ if (code) {
cm_ReleaseUser(userp);
- return CM_ERROR_NOSUCHPATH;
+ return code;
}
- code = cm_NameI(cm_rootSCachep, spacep->data, caseFold,
- userp, tidPathp, &req, &oldDscp);
-
- if (code) {
- cm_ReleaseUser(userp);
- return code;
- }
- smb_StripLastComponent(spacep->data, &newLastNamep, newPathp);
- code = cm_NameI(cm_rootSCachep, spacep->data, caseFold,
- userp, tidPathp, &req, &newDscp);
+ smb_StripLastComponent(spacep->data, &newLastNamep, newPathp);
+ code = cm_NameI(cm_rootSCachep, spacep->data, caseFold,
+ userp, tidPathp, &req, &newDscp);
- if (code) {
- cm_ReleaseSCache(oldDscp);
- cm_ReleaseUser(userp);
- return code;
- }
+ if (code) {
+ cm_ReleaseSCache(oldDscp);
+ cm_ReleaseUser(userp);
+ return code;
+ }
- /* otherwise, oldDscp and newDscp point to the corresponding directories.
- * next, get the component names, and lower case them.
- */
+ /* otherwise, oldDscp and newDscp point to the corresponding directories.
+ * next, get the component names, and lower case them.
+ */
- /* handle the old name first */
- if (!oldLastNamep)
- oldLastNamep = oldPathp;
- else
- oldLastNamep++;
+ /* handle the old name first */
+ if (!oldLastNamep)
+ oldLastNamep = oldPathp;
+ else
+ oldLastNamep++;
- /* and handle the new name, too */
- if (!newLastNamep)
- newLastNamep = newPathp;
- else
- newLastNamep++;
+ /* and handle the new name, too */
+ if (!newLastNamep)
+ newLastNamep = newPathp;
+ else
+ newLastNamep++;
/* TODO: The old name could be a wildcard. The new name must not be */
-
- /* do the vnode call */
- rock.odscp = oldDscp;
- rock.ndscp = newDscp;
- rock.userp = userp;
- rock.reqp = &req;
- rock.vcp = vcp;
- rock.maskp = oldLastNamep;
- rock.flags = ((strchr(oldLastNamep, '~') != NULL) ? SMB_MASKFLAG_TILDE : 0);
- rock.newNamep = newLastNamep;
+
+ /* do the vnode call */
+ rock.odscp = oldDscp;
+ rock.ndscp = newDscp;
+ rock.userp = userp;
+ rock.reqp = &req;
+ rock.vcp = vcp;
+ rock.maskp = oldLastNamep;
+ rock.flags = ((strchr(oldLastNamep, '~') != NULL) ? SMB_MASKFLAG_TILDE : 0);
+ rock.newNamep = newLastNamep;
/* Check if the file already exists; if so return error */
- code = cm_Lookup(newDscp,newLastNamep,CM_FLAG_CHECKPATH,userp,&req,&tmpscp);
- if ((code != CM_ERROR_NOSUCHFILE) && (code != CM_ERROR_NOSUCHPATH) && (code != CM_ERROR_NOSUCHVOLUME) ) {
+ code = cm_Lookup(newDscp,newLastNamep,CM_FLAG_CHECKPATH,userp,&req,&tmpscp);
+ if ((code != CM_ERROR_NOSUCHFILE) && (code != CM_ERROR_NOSUCHPATH) && (code != CM_ERROR_NOSUCHVOLUME) ) {
osi_Log2(smb_logp, " lookup returns %ld for [%s]", code,
osi_LogSaveString(afsd_logp, newLastNamep));
-
+
/* Check if the old and the new names differ only in case. If so return
* success, else return CM_ERROR_EXISTS
*/
code = CM_ERROR_EXISTS;
}
- if(tmpscp != NULL)
+ if(tmpscp != NULL)
cm_ReleaseSCache(tmpscp);
cm_ReleaseSCache(newDscp);
cm_ReleaseSCache(oldDscp);
cm_ReleaseUser(userp);
- return code;
- }
+ return code;
+ }
/* Now search the directory for the pattern, and do the appropriate rename when found */
- thyper.LowPart = 0; /* search dir from here */
+ thyper.LowPart = 0; /* search dir from here */
thyper.HighPart = 0;
code = cm_ApplyDir(oldDscp, smb_RenameProc, &rock, &thyper, userp, &req, NULL);
if (code == CM_ERROR_STOPNOW)
- code = 0;
- else if (code == 0)
- code = CM_ERROR_NOSUCHFILE;
-
- /* Handle Change Notification */
- /*
- * Being lazy, not distinguishing between files and dirs in this
- * filter, since we'd have to do a lookup.
- */
- filter = FILE_NOTIFY_CHANGE_FILE_NAME | FILE_NOTIFY_CHANGE_DIR_NAME;
- if (oldDscp == newDscp) {
- if (oldDscp->flags & CM_SCACHEFLAG_ANYWATCH)
- smb_NotifyChange(FILE_ACTION_RENAMED_OLD_NAME,
- filter, oldDscp, oldLastNamep,
- newLastNamep, TRUE);
- } else {
- if (oldDscp->flags & CM_SCACHEFLAG_ANYWATCH)
- smb_NotifyChange(FILE_ACTION_RENAMED_OLD_NAME,
- filter, oldDscp, oldLastNamep,
- NULL, TRUE);
- if (newDscp->flags & CM_SCACHEFLAG_ANYWATCH)
- smb_NotifyChange(FILE_ACTION_RENAMED_NEW_NAME,
- filter, newDscp, newLastNamep,
- NULL, TRUE);
- }
+ code = 0;
+ else if (code == 0)
+ code = CM_ERROR_NOSUCHFILE;
+
+ /* Handle Change Notification */
+ /*
+ * Being lazy, not distinguishing between files and dirs in this
+ * filter, since we'd have to do a lookup.
+ */
+ filter = FILE_NOTIFY_CHANGE_FILE_NAME | FILE_NOTIFY_CHANGE_DIR_NAME;
+ if (oldDscp == newDscp) {
+ if (oldDscp->flags & CM_SCACHEFLAG_ANYWATCH)
+ smb_NotifyChange(FILE_ACTION_RENAMED_OLD_NAME,
+ filter, oldDscp, oldLastNamep,
+ newLastNamep, TRUE);
+ } else {
+ if (oldDscp->flags & CM_SCACHEFLAG_ANYWATCH)
+ smb_NotifyChange(FILE_ACTION_RENAMED_OLD_NAME,
+ filter, oldDscp, oldLastNamep,
+ NULL, TRUE);
+ if (newDscp->flags & CM_SCACHEFLAG_ANYWATCH)
+ smb_NotifyChange(FILE_ACTION_RENAMED_NEW_NAME,
+ filter, newDscp, newLastNamep,
+ NULL, TRUE);
+ }
if(tmpscp != NULL)
cm_ReleaseSCache(tmpscp);
cm_ReleaseUser(userp);
- cm_ReleaseSCache(oldDscp);
- cm_ReleaseSCache(newDscp);
- return code;
+ cm_ReleaseSCache(oldDscp);
+ cm_ReleaseSCache(newDscp);
+ return code;
}
+long
+smb_Link(smb_vc_t *vcp, smb_packet_t *inp, char * oldPathp, char * newPathp)
+{
+ long code = 0;
+ cm_space_t *spacep = NULL;
+ cm_scache_t *oldDscp = NULL;
+ cm_scache_t *newDscp = NULL;
+ cm_scache_t *tmpscp= NULL;
+ cm_scache_t *tmpscp2 = NULL;
+ cm_scache_t *sscp = NULL;
+ char *oldLastNamep;
+ char *newLastNamep;
+ cm_user_t *userp;
+ int caseFold;
+ char *tidPathp;
+ DWORD filter;
+ cm_req_t req;
+
+ userp = smb_GetUser(vcp, inp);
+
+ code = smb_LookupTIDPath(vcp, ((smb_t *)inp)->tid, &tidPathp);
+ if (code) {
+ cm_ReleaseUser(userp);
+ return CM_ERROR_NOSUCHPATH;
+ }
+
+ cm_InitReq(&req);
+
+ caseFold = CM_FLAG_FOLLOW | CM_FLAG_CASEFOLD;
+
+ spacep = inp->spacep;
+ smb_StripLastComponent(spacep->data, &oldLastNamep, oldPathp);
+
+ code = cm_NameI(cm_rootSCachep, spacep->data, caseFold,
+ userp, tidPathp, &req, &oldDscp);
+ if (code) {
+ cm_ReleaseUser(userp);
+ return code;
+ }
+
+ smb_StripLastComponent(spacep->data, &newLastNamep, newPathp);
+ code = cm_NameI(cm_rootSCachep, spacep->data, caseFold,
+ userp, tidPathp, &req, &newDscp);
+ if (code) {
+ cm_ReleaseSCache(oldDscp);
+ cm_ReleaseUser(userp);
+ return code;
+ }
+
+ /* Now, although we did two lookups for the two directories (because the same
+ * directory can be referenced through different paths), we only allow hard links
+ * within the same directory. */
+ if (oldDscp != newDscp) {
+ cm_ReleaseSCache(oldDscp);
+ cm_ReleaseSCache(newDscp);
+ cm_ReleaseUser(userp);
+ return CM_ERROR_CROSSDEVLINK;
+ }
+
+ /* handle the old name first */
+ if (!oldLastNamep)
+ oldLastNamep = oldPathp;
+ else
+ oldLastNamep++;
+
+ /* and handle the new name, too */
+ if (!newLastNamep)
+ newLastNamep = newPathp;
+ else
+ newLastNamep++;
+
+ /* now lookup the old name */
+ osi_Log1(smb_logp," looking up [%s]", osi_LogSaveString(smb_logp,oldLastNamep));
+ code = cm_Lookup(oldDscp, oldLastNamep, CM_FLAG_CHECKPATH | CM_FLAG_CASEFOLD, userp, &req, &sscp);
+ if (code) {
+ cm_ReleaseSCache(oldDscp);
+ cm_ReleaseSCache(newDscp);
+ cm_ReleaseUser(userp);
+ return code;
+ }
+
+ /* Check if the file already exists; if so return error */
+ code = cm_Lookup(newDscp,newLastNamep,CM_FLAG_CHECKPATH,userp,&req,&tmpscp);
+ if ((code != CM_ERROR_NOSUCHFILE) && (code != CM_ERROR_NOSUCHPATH) && (code != CM_ERROR_NOSUCHVOLUME) ) {
+ osi_Log2(smb_logp, " lookup returns %ld for [%s]", code,
+ osi_LogSaveString(afsd_logp, newLastNamep));
+
+ /* if the existing link is to the same file, then we return success */
+ if (!code) {
+ if(sscp == tmpscp) {
+ code = 0;
+ } else {
+ osi_Log0(smb_logp, "Can't create hardlink. Target already exists");
+ code = CM_ERROR_EXISTS;
+ }
+ }
+
+ if (tmpscp != NULL)
+ cm_ReleaseSCache(tmpscp);
+ cm_ReleaseSCache(sscp);
+ cm_ReleaseSCache(newDscp);
+ cm_ReleaseSCache(oldDscp);
+ cm_ReleaseUser(userp);
+ return code;
+ }
+
+ /* now create the hardlink */
+ osi_Log1(smb_logp," Attempting to create new link [%s]", osi_LogSaveString(smb_logp, newLastNamep));
+ code = cm_Link(newDscp, newLastNamep, sscp, 0, userp, &req);
+ osi_Log1(smb_logp," Link returns %d", code);
+
+ /* Handle Change Notification */
+ if (code == 0) {
+ filter = (sscp->fileType == CM_SCACHETYPE_FILE)? FILE_NOTIFY_CHANGE_FILE_NAME : FILE_NOTIFY_CHANGE_DIR_NAME;
+ if (newDscp->flags & CM_SCACHEFLAG_ANYWATCH)
+ smb_NotifyChange(FILE_ACTION_ADDED,
+ filter, newDscp, newLastNamep,
+ NULL, TRUE);
+ }
+
+ if (tmpscp != NULL)
+ cm_ReleaseSCache(tmpscp);
+ cm_ReleaseUser(userp);
+ cm_ReleaseSCache(sscp);
+ cm_ReleaseSCache(oldDscp);
+ cm_ReleaseSCache(newDscp);
+ return code;
+}
+
+long
+smb_ReceiveCoreRename(smb_vc_t *vcp, smb_packet_t *inp, smb_packet_t *outp)
+{
+ char *oldPathp;
+ char *newPathp;
+ char *tp;
+
+ tp = smb_GetSMBData(inp, NULL);
+ oldPathp = smb_ParseASCIIBlock(tp, &tp);
+ newPathp = smb_ParseASCIIBlock(tp, &tp);
+
+ osi_Log2(smb_logp, "smb rename [%s] to [%s]",
+ osi_LogSaveString(smb_logp, oldPathp),
+ osi_LogSaveString(smb_logp, newPathp));
+
+ return smb_Rename(vcp,inp,oldPathp,newPathp,0);
+}
+
+
+
typedef struct smb_rmdirRock {
cm_scache_t *dscp;
cm_user_t *userp;
int temp;
unsigned char *tp;
unsigned short errCode;
- unsigned long NTStatus;
+ unsigned long NTStatus;
int noSend;
unsigned char errClass;
- unsigned int oldGen;
- DWORD oldTime, newTime;
+ unsigned int oldGen;
+ DWORD oldTime, newTime;
- /* get easy pointer to the data */
- smbp = (smb_t *) inp->data;
+ /* get easy pointer to the data */
+ smbp = (smb_t *) inp->data;
- if (!(outp->flags & SMB_PACKETFLAG_SUSPENDED)) {
+ if (!(outp->flags & SMB_PACKETFLAG_SUSPENDED)) {
/* setup the basic parms for the initial request in the packet */
- inp->inCom = smbp->com;
+ inp->inCom = smbp->com;
inp->wctp = &smbp->wct;
inp->inCount = 0;
- inp->ncb_length = ncbp->ncb_length;
- }
+ inp->ncb_length = ncbp->ncb_length;
+ }
noSend = 0;
- /* Sanity check */
- if (ncbp->ncb_length < offsetof(struct smb, vdata)) {
- /* log it and discard it */
+ /* Sanity check */
+ if (ncbp->ncb_length < offsetof(struct smb, vdata)) {
+ /* log it and discard it */
#ifndef DJGPP
- HANDLE h;
- char *ptbuf[1];
- char s[100];
- h = RegisterEventSource(NULL, AFS_DAEMON_EVENT_NAME);
- sprintf(s, "SMB message too short, len %d", ncbp->ncb_length);
- ptbuf[0] = s;
- ReportEvent(h, EVENTLOG_WARNING_TYPE, 0, 1007, NULL,
- 1, ncbp->ncb_length, ptbuf, inp);
- DeregisterEventSource(h);
+ HANDLE h;
+ char *ptbuf[1];
+ char s[100];
+ h = RegisterEventSource(NULL, AFS_DAEMON_EVENT_NAME);
+ sprintf(s, "SMB message too short, len %d", ncbp->ncb_length);
+ ptbuf[0] = s;
+ ReportEvent(h, EVENTLOG_WARNING_TYPE, 0, 1007, NULL,
+ 1, ncbp->ncb_length, ptbuf, inp);
+ DeregisterEventSource(h);
#else /* DJGPP */
osi_Log1(smb_logp, "SMB message too short, len %d", ncbp->ncb_length);
#endif /* !DJGPP */
- return;
- }
+ return;
+ }
- /* We are an ongoing op */
- thrd_Increment(&ongoingOps);
+ /* We are an ongoing op */
+ thrd_Increment(&ongoingOps);
/* set up response packet for receiving output */
- if (!(outp->flags & SMB_PACKETFLAG_SUSPENDED))
+ if (!(outp->flags & SMB_PACKETFLAG_SUSPENDED))
smb_FormatResponsePacket(vcp, inp, outp);
outWctp = outp->wctp;
- /* Remember session generation number and time */
- oldGen = sessionGen;
- oldTime = GetCurrentTime();
+ /* Remember session generation number and time */
+ oldGen = sessionGen;
+ oldTime = GetCurrentTime();
- while(inp->inCom != 0xff) {
+ while (inp->inCom != 0xff) {
dp = &smb_dispatchTable[inp->inCom];
- if (outp->flags & SMB_PACKETFLAG_SUSPENDED) {
- outp->flags &= ~SMB_PACKETFLAG_SUSPENDED;
- code = outp->resumeCode;
- goto resume;
- }
+ if (outp->flags & SMB_PACKETFLAG_SUSPENDED) {
+ outp->flags &= ~SMB_PACKETFLAG_SUSPENDED;
+ code = outp->resumeCode;
+ goto resume;
+ }
/* process each request in the packet; inCom, wctp and inCount
* are already set up.
*/
- osi_Log2(smb_logp, "SMB received op 0x%x lsn %d", inp->inCom,
- ncbp->ncb_lsn);
+ osi_Log2(smb_logp, "SMB received op 0x%x lsn %d", inp->inCom,
+ ncbp->ncb_lsn);
- /* now do the dispatch */
- /* start by formatting the response record a little, as a default */
+ /* now do the dispatch */
+ /* start by formatting the response record a little, as a default */
if (dp->flags & SMB_DISPATCHFLAG_CHAINED) {
- outWctp[0] = 2;
+ outWctp[0] = 2;
outWctp[1] = 0xff; /* no operation */
outWctp[2] = 0; /* padding */
outWctp[3] = 0;
outWctp[4] = 0;
}
- else {
- /* not a chained request, this is a more reasonable default */
+ else {
+ /* not a chained request, this is a more reasonable default */
outWctp[0] = 0; /* wct of zero */
outWctp[1] = 0; /* and bcc (word) of zero */
outWctp[2] = 0;
- }
+ }
- /* once set, stays set. Doesn't matter, since we never chain
+ /* once set, stays set. Doesn't matter, since we never chain
* "no response" calls.
*/
- if (dp->flags & SMB_DISPATCHFLAG_NORESPONSE)
+ if (dp->flags & SMB_DISPATCHFLAG_NORESPONSE)
noSend = 1;
if (dp->procp) {
- /* we have a recognized operation */
-
- if (inp->inCom == 0x1d)
- /* Raw Write */
- code = smb_ReceiveCoreWriteRaw (vcp, inp, outp,
- rwcp);
- else {
- osi_LogEvent("AFS Dispatch %s",(myCrt_Dispatch(inp->inCom)),"vcp[%x] lana[%d] lsn[%d]",(int)vcp,vcp->lana,vcp->lsn);
- osi_Log4(smb_logp,"Dispatch %s vcp[%x] lana[%d] lsn[%d]",(myCrt_Dispatch(inp->inCom)),vcp,vcp->lana,vcp->lsn);
- code = (*(dp->procp)) (vcp, inp, outp);
- osi_LogEvent("AFS Dispatch return",NULL,"Code[%d]",(code==0)?0:code-CM_ERROR_BASE);
- osi_Log1(smb_logp,"Dispatch return code[%d]",(code==0)?0:code-CM_ERROR_BASE);
- }
+ /* we have a recognized operation */
- if (oldGen != sessionGen) {
+ if (inp->inCom == 0x1d)
+ /* Raw Write */
+ code = smb_ReceiveCoreWriteRaw (vcp, inp, outp,
+ rwcp);
+ else {
+ osi_LogEvent("AFS Dispatch %s",(myCrt_Dispatch(inp->inCom)),"vcp[%x] lana[%d] lsn[%d]",(int)vcp,vcp->lana,vcp->lsn);
+ osi_Log4(smb_logp,"Dispatch %s vcp[%x] lana[%d] lsn[%d]",(myCrt_Dispatch(inp->inCom)),vcp,vcp->lana,vcp->lsn);
+ code = (*(dp->procp)) (vcp, inp, outp);
+ osi_LogEvent("AFS Dispatch return",NULL,"Code[%d]",(code==0)?0:code-CM_ERROR_BASE);
+ osi_Log1(smb_logp,"Dispatch return code[%d]",(code==0)?0:code-CM_ERROR_BASE);
+#ifdef LOG_PACKET
+ if ( code == CM_ERROR_BADSMB ||
+ code == CM_ERROR_BADOP )
+ smb_LogPacket(inp);
+#endif /* LOG_PACKET */
+ }
+
+ if (oldGen != sessionGen) {
#ifndef DJGPP
- HANDLE h;
- char *ptbuf[1];
- char s[100];
- newTime = GetCurrentTime();
- h = RegisterEventSource(NULL, AFS_DAEMON_EVENT_NAME);
- sprintf(s, "Pkt straddled session startup, took %d ms, ncb length %d",
- newTime - oldTime, ncbp->ncb_length);
- ptbuf[0] = s;
- ReportEvent(h, EVENTLOG_WARNING_TYPE, 0,
- 1005, NULL, 1, ncbp->ncb_length, ptbuf, smbp);
- DeregisterEventSource(h);
+ HANDLE h;
+ char *ptbuf[1];
+ char s[100];
+ newTime = GetCurrentTime();
+ h = RegisterEventSource(NULL, AFS_DAEMON_EVENT_NAME);
+ sprintf(s, "Pkt straddled session startup, took %d ms, ncb length %d",
+ newTime - oldTime, ncbp->ncb_length);
+ ptbuf[0] = s;
+ ReportEvent(h, EVENTLOG_WARNING_TYPE, 0,
+ 1005, NULL, 1, ncbp->ncb_length, ptbuf, smbp);
+ DeregisterEventSource(h);
#endif /* !DJGPP */
- osi_Log1(smb_logp, "Pkt straddled session startup, "
- "ncb length %d", ncbp->ncb_length);
- }
+ osi_Log1(smb_logp, "Pkt straddled session startup, "
+ "ncb length %d", ncbp->ncb_length);
+ }
}
else {
- /* bad opcode, fail the request, after displaying it */
-#ifdef NOTSERVICE
+ /* bad opcode, fail the request, after displaying it */
+ osi_Log1(smb_logp, "Received bad SMB req 0x%X", inp->inCom);
+#ifdef LOG_PACKET
smb_LogPacket(inp);
-#endif /* NOTSERVICE */
+#endif /* LOG_PACKET */
#ifndef DJGPP
- if (showErrors) {
- sprintf(tbuffer, "Received bad SMB req 0x%x", inp->inCom);
+ if (showErrors) {
+ sprintf(tbuffer, "Received bad SMB req 0x%x", inp->inCom);
code = (*smb_MBfunc)(NULL, tbuffer, "Cancel: don't show again",
- MB_OKCANCEL|MB_SERVICE_NOTIFICATION);
- if (code == IDCANCEL) showErrors = 0;
- }
+ MB_OKCANCEL|MB_SERVICE_NOTIFICATION);
+ if (code == IDCANCEL)
+ showErrors = 0;
+ }
#endif /* DJGPP */
code = CM_ERROR_BADOP;
}
- /* catastrophic failure: log as much as possible */
- if (code == CM_ERROR_BADSMB) {
+ /* catastrophic failure: log as much as possible */
+ if (code == CM_ERROR_BADSMB) {
#ifndef DJGPP
- HANDLE h;
- char *ptbuf[1];
- char s[100];
+ HANDLE h;
+ char *ptbuf[1];
+ char s[100];
- osi_Log1(smb_logp,
+ osi_Log1(smb_logp,
"Invalid SMB, ncb_length %d",
ncbp->ncb_length);
- h = RegisterEventSource(NULL, AFS_DAEMON_EVENT_NAME);
- sprintf(s, "Invalid SMB message, length %d",
+ h = RegisterEventSource(NULL, AFS_DAEMON_EVENT_NAME);
+ sprintf(s, "Invalid SMB message, length %d",
ncbp->ncb_length);
- ptbuf[0] = s;
- ReportEvent(h, EVENTLOG_ERROR_TYPE, 0, 1002, NULL,
+ ptbuf[0] = s;
+ ReportEvent(h, EVENTLOG_ERROR_TYPE, 0, 1002, NULL,
1, ncbp->ncb_length, ptbuf, smbp);
- DeregisterEventSource(h);
-#ifdef NOTSERVICE
+ DeregisterEventSource(h);
+#ifdef LOG_PACKET
smb_LogPacket(inp);
-#endif /* NOTSERVICE */
+#endif /* LOG_PACKET */
#endif /* !DJGPP */
osi_Log1(smb_logp, "Invalid SMB message, length %d",
ncbp->ncb_length);
- code = CM_ERROR_INVAL;
- }
+ code = CM_ERROR_INVAL;
+ }
- if (outp->flags & SMB_PACKETFLAG_NOSEND) {
- thrd_Decrement(&ongoingOps);
- return;
- }
+ if (outp->flags & SMB_PACKETFLAG_NOSEND) {
+ thrd_Decrement(&ongoingOps);
+ return;
+ }
resume:
- /* now, if we failed, turn the current response into an empty
+ /* now, if we failed, turn the current response into an empty
* one, and fill in the response packet's error code.
*/
- if (code) {
- if (vcp->flags & SMB_VCFLAG_STATUS32) {
- smb_MapNTError(code, &NTStatus);
- outWctp = outp->wctp;
- smbp = (smb_t *) &outp->data;
- if (code != CM_ERROR_PARTIALWRITE
- && code != CM_ERROR_BUFFERTOOSMALL
- && code != CM_ERROR_GSSCONTINUE) {
- /* nuke wct and bcc. For a partial
- * write or an in-process authentication handshake,
+ if (code) {
+ if (vcp->flags & SMB_VCFLAG_STATUS32) {
+ smb_MapNTError(code, &NTStatus);
+ outWctp = outp->wctp;
+ smbp = (smb_t *) &outp->data;
+ if (code != CM_ERROR_PARTIALWRITE
+ && code != CM_ERROR_BUFFERTOOSMALL
+ && code != CM_ERROR_GSSCONTINUE) {
+ /* nuke wct and bcc. For a partial
+ * write or an in-process authentication handshake,
* assume they're OK.
- */
- *outWctp++ = 0;
- *outWctp++ = 0;
- *outWctp++ = 0;
- }
- smbp->rcls = (unsigned char) (NTStatus & 0xff);
- smbp->reh = (unsigned char) ((NTStatus >> 8) & 0xff);
- smbp->errLow = (unsigned char) ((NTStatus >> 16) & 0xff);
- smbp->errHigh = (unsigned char) ((NTStatus >> 24) & 0xff);
- smbp->flg2 |= 0x4000;
- break;
- }
- else {
+ */
+ *outWctp++ = 0;
+ *outWctp++ = 0;
+ *outWctp++ = 0;
+ }
+ smbp->rcls = (unsigned char) (NTStatus & 0xff);
+ smbp->reh = (unsigned char) ((NTStatus >> 8) & 0xff);
+ smbp->errLow = (unsigned char) ((NTStatus >> 16) & 0xff);
+ smbp->errHigh = (unsigned char) ((NTStatus >> 24) & 0xff);
+ smbp->flg2 |= 0x4000;
+ break;
+ }
+ else {
smb_MapCoreError(code, vcp, &errCode, &errClass);
- outWctp = outp->wctp;
- smbp = (smb_t *) &outp->data;
- if (code != CM_ERROR_PARTIALWRITE) {
- /* nuke wct and bcc. For a partial
- * write, assume they're OK.
- */
- *outWctp++ = 0;
- *outWctp++ = 0;
- *outWctp++ = 0;
- }
- smbp->errLow = (unsigned char) (errCode & 0xff);
- smbp->errHigh = (unsigned char) ((errCode >> 8) & 0xff);
+ outWctp = outp->wctp;
+ smbp = (smb_t *) &outp->data;
+ if (code != CM_ERROR_PARTIALWRITE) {
+ /* nuke wct and bcc. For a partial
+ * write, assume they're OK.
+ */
+ *outWctp++ = 0;
+ *outWctp++ = 0;
+ *outWctp++ = 0;
+ }
+ smbp->errLow = (unsigned char) (errCode & 0xff);
+ smbp->errHigh = (unsigned char) ((errCode >> 8) & 0xff);
smbp->rcls = errClass;
- break;
- }
- } /* error occurred */
-
+ break;
+ }
+ } /* error occurred */
+
/* if we're here, we've finished one request. Look to see if
- * this is a chained opcode. If it is, setup things to process
- * the chained request, and setup the output buffer to hold the
- * chained response. Start by finding the next input record.
+ * this is a chained opcode. If it is, setup things to process
+ * the chained request, and setup the output buffer to hold the
+ * chained response. Start by finding the next input record.
*/
if (!(dp->flags & SMB_DISPATCHFLAG_CHAINED))
break; /* not a chained req */
/* and now append the next output request to the end of this
* last request. Begin by finding out where the last response
- * ends, since that's where we'll put our new response.
+ * ends, since that's where we'll put our new response.
*/
outWctp = outp->wctp; /* ptr to out parameters */
osi_assert (outWctp[0] >= 2); /* need this for all chained requests */
tp = outWctp + nparms + 1; /* now points to bcc field */
nbytes = tp[0] + (tp[1] << 8); /* # of data bytes */
tp += 2 /* for the count itself */ + nbytes;
- /* tp now points to the new output record; go back and patch the
+ /* tp now points to the new output record; go back and patch the
* second parameter (off2) to point to the new record.
*/
- temp = (unsigned int)tp - ((unsigned int) outp->data);
+ temp = (unsigned int)tp - ((unsigned int) outp->data);
outWctp[3] = (unsigned char) (temp & 0xff);
outWctp[4] = (unsigned char) ((temp >> 8) & 0xff);
outWctp[2] = 0; /* padding */
outWctp[1] = inp->inCom; /* next opcode */
- /* finally, setup for the next iteration */
+ /* finally, setup for the next iteration */
outp->wctp = tp;
- outWctp = tp;
- } /* while loop over all requests in the packet */
-
- /* done logging out, turn off logging-out flag */
- if (!(inp->flags & SMB_PACKETFLAG_PROFILE_UPDATE_OK)) {
- vcp->justLoggedOut = NULL;
- if (loggedOut) {
- loggedOut = 0;
- free(loggedOutName);
- loggedOutName = NULL;
- smb_ReleaseUID(loggedOutUserp);
- loggedOutUserp = NULL;
- }
- }
+ outWctp = tp;
+ } /* while loop over all requests in the packet */
+
+ /* done logging out, turn off logging-out flag */
+ if (!(inp->flags & SMB_PACKETFLAG_PROFILE_UPDATE_OK)) {
+ vcp->justLoggedOut = NULL;
+ if (loggedOut) {
+ loggedOut = 0;
+ free(loggedOutName);
+ loggedOutName = NULL;
+ smb_ReleaseUID(loggedOutUserp);
+ loggedOutUserp = NULL;
+ }
+ }
/* now send the output packet, and return */
if (!noSend)
- smb_SendPacket(vcp, outp);
+ smb_SendPacket(vcp, outp);
thrd_Decrement(&ongoingOps);
if (!(vcp->flags & SMB_VCFLAG_ALREADYDEAD)) {
"Replacing active_vcp %x with %x", active_vcp, vcp);
}
smb_HoldVC(vcp);
- active_vcp = vcp;
- last_msg_time = GetCurrentTime();
- }
+ active_vcp = vcp;
+ last_msg_time = GetCurrentTime();
+ }
else if (active_vcp == vcp) {
- smb_ReleaseVC(active_vcp);
- active_vcp = NULL;
+ smb_ReleaseVC(active_vcp);
+ active_vcp = NULL;
}
return;
fprintf(stderr, "New session(ncb_lsn,ncb_lana_num) %d,%d starting from host "
"%s\n",
ncbp->ncb_lsn,ncbp->ncb_lana_num, rname);
-#endif
+#endif /* NOTSERVICE */
osi_Log4(smb_logp, "New session(ncb_lsn,ncb_lana_num) (%d,%d) starting from host %s, %d ongoing ops",
ncbp->ncb_lsn,ncbp->ncb_lana_num, osi_LogSaveString(smb_logp, rname), ongoingOps);
retHandle = thrd_CreateEvent(NULL, FALSE, FALSE, eventName);
if ( GetLastError() == ERROR_ALREADY_EXISTS )
afsi_log("Event Object Already Exists: %s", eventName);
- for (i = 0; i < smb_NumServerThreads; i++) {
- NCBreturns[i] = malloc(NCBmax * sizeof(EVENT_HANDLE));
- NCBreturns[i][0] = retHandle;
- }
- for (i = 1; i <= nThreads; i++)
- InitNCBslot(i);
- numNCBs = nThreads + 1;
-
- /* Initialize dispatch table */
- memset(&smb_dispatchTable, 0, sizeof(smb_dispatchTable));
- smb_dispatchTable[0x00].procp = smb_ReceiveCoreMakeDir;
- smb_dispatchTable[0x01].procp = smb_ReceiveCoreRemoveDir;
- smb_dispatchTable[0x02].procp = smb_ReceiveCoreOpen;
- smb_dispatchTable[0x03].procp = smb_ReceiveCoreCreate;
- smb_dispatchTable[0x04].procp = smb_ReceiveCoreClose;
- smb_dispatchTable[0x05].procp = smb_ReceiveCoreFlush;
- smb_dispatchTable[0x06].procp = smb_ReceiveCoreUnlink;
- smb_dispatchTable[0x07].procp = smb_ReceiveCoreRename;
- smb_dispatchTable[0x08].procp = smb_ReceiveCoreGetFileAttributes;
- smb_dispatchTable[0x09].procp = smb_ReceiveCoreSetFileAttributes;
- smb_dispatchTable[0x0a].procp = smb_ReceiveCoreRead;
- smb_dispatchTable[0x0b].procp = smb_ReceiveCoreWrite;
- smb_dispatchTable[0x0c].procp = smb_ReceiveCoreLockRecord;
- smb_dispatchTable[0x0d].procp = smb_ReceiveCoreUnlockRecord;
- smb_dispatchTable[0x0e].procp = smb_SendCoreBadOp; /* create temporary */
- smb_dispatchTable[0x0f].procp = smb_ReceiveCoreCreate;
- smb_dispatchTable[0x10].procp = smb_ReceiveCoreCheckPath;
- smb_dispatchTable[0x11].procp = smb_SendCoreBadOp; /* process exit */
- smb_dispatchTable[0x12].procp = smb_ReceiveCoreSeek;
- smb_dispatchTable[0x1a].procp = smb_ReceiveCoreReadRaw;
- /* Set NORESPONSE because smb_ReceiveCoreReadRaw() does the responses itself */
- smb_dispatchTable[0x1a].flags |= SMB_DISPATCHFLAG_NORESPONSE;
- smb_dispatchTable[0x1d].procp = smb_ReceiveCoreWriteRawDummy;
- smb_dispatchTable[0x22].procp = smb_ReceiveV3SetAttributes;
- smb_dispatchTable[0x23].procp = smb_ReceiveV3GetAttributes;
- smb_dispatchTable[0x24].procp = smb_ReceiveV3LockingX;
- smb_dispatchTable[0x24].flags |= SMB_DISPATCHFLAG_CHAINED;
- smb_dispatchTable[0x25].procp = smb_ReceiveV3Trans;
- smb_dispatchTable[0x25].flags |= SMB_DISPATCHFLAG_NORESPONSE;
- smb_dispatchTable[0x26].procp = smb_ReceiveV3Trans;
- smb_dispatchTable[0x26].flags |= SMB_DISPATCHFLAG_NORESPONSE;
- smb_dispatchTable[0x29].procp = smb_SendCoreBadOp; /* copy file */
- smb_dispatchTable[0x2b].procp = smb_ReceiveCoreEcho;
- /* Set NORESPONSE because smb_ReceiveCoreEcho() does the responses itself */
- smb_dispatchTable[0x2b].flags |= SMB_DISPATCHFLAG_NORESPONSE;
+ for (i = 0; i < smb_NumServerThreads; i++) {
+ NCBreturns[i] = malloc(NCBmax * sizeof(EVENT_HANDLE));
+ NCBreturns[i][0] = retHandle;
+ }
+ for (i = 1; i <= nThreads; i++)
+ InitNCBslot(i);
+ numNCBs = nThreads + 1;
+
+ /* Initialize dispatch table */
+ memset(&smb_dispatchTable, 0, sizeof(smb_dispatchTable));
+ /* Prepare the table for unknown operations */
+ for(i=0; i<= SMB_NOPCODES; i++) {
+ smb_dispatchTable[i].procp = smb_SendCoreBadOp;
+ }
+ /* Fill in the ones we do know */
+ smb_dispatchTable[0x00].procp = smb_ReceiveCoreMakeDir;
+ smb_dispatchTable[0x01].procp = smb_ReceiveCoreRemoveDir;
+ smb_dispatchTable[0x02].procp = smb_ReceiveCoreOpen;
+ smb_dispatchTable[0x03].procp = smb_ReceiveCoreCreate;
+ smb_dispatchTable[0x04].procp = smb_ReceiveCoreClose;
+ smb_dispatchTable[0x05].procp = smb_ReceiveCoreFlush;
+ smb_dispatchTable[0x06].procp = smb_ReceiveCoreUnlink;
+ smb_dispatchTable[0x07].procp = smb_ReceiveCoreRename;
+ smb_dispatchTable[0x08].procp = smb_ReceiveCoreGetFileAttributes;
+ smb_dispatchTable[0x09].procp = smb_ReceiveCoreSetFileAttributes;
+ smb_dispatchTable[0x0a].procp = smb_ReceiveCoreRead;
+ smb_dispatchTable[0x0b].procp = smb_ReceiveCoreWrite;
+ smb_dispatchTable[0x0c].procp = smb_ReceiveCoreLockRecord;
+ smb_dispatchTable[0x0d].procp = smb_ReceiveCoreUnlockRecord;
+ smb_dispatchTable[0x0e].procp = smb_SendCoreBadOp; /* create temporary */
+ smb_dispatchTable[0x0f].procp = smb_ReceiveCoreCreate;
+ smb_dispatchTable[0x10].procp = smb_ReceiveCoreCheckPath;
+ smb_dispatchTable[0x11].procp = smb_SendCoreBadOp; /* process exit */
+ smb_dispatchTable[0x12].procp = smb_ReceiveCoreSeek;
+ smb_dispatchTable[0x1a].procp = smb_ReceiveCoreReadRaw;
+ /* Set NORESPONSE because smb_ReceiveCoreReadRaw() does the responses itself */
+ smb_dispatchTable[0x1a].flags |= SMB_DISPATCHFLAG_NORESPONSE;
+ smb_dispatchTable[0x1d].procp = smb_ReceiveCoreWriteRawDummy;
+ smb_dispatchTable[0x22].procp = smb_ReceiveV3SetAttributes;
+ smb_dispatchTable[0x23].procp = smb_ReceiveV3GetAttributes;
+ smb_dispatchTable[0x24].procp = smb_ReceiveV3LockingX;
+ smb_dispatchTable[0x24].flags |= SMB_DISPATCHFLAG_CHAINED;
+ smb_dispatchTable[0x25].procp = smb_ReceiveV3Trans;
+ smb_dispatchTable[0x25].flags |= SMB_DISPATCHFLAG_NORESPONSE;
+ smb_dispatchTable[0x26].procp = smb_ReceiveV3Trans;
+ smb_dispatchTable[0x26].flags |= SMB_DISPATCHFLAG_NORESPONSE;
+ smb_dispatchTable[0x29].procp = smb_SendCoreBadOp; /* copy file */
+ smb_dispatchTable[0x2b].procp = smb_ReceiveCoreEcho;
+ /* Set NORESPONSE because smb_ReceiveCoreEcho() does the responses itself */
+ smb_dispatchTable[0x2b].flags |= SMB_DISPATCHFLAG_NORESPONSE;
smb_dispatchTable[0x2d].procp = smb_ReceiveV3OpenX;
smb_dispatchTable[0x2d].flags |= SMB_DISPATCHFLAG_CHAINED;
smb_dispatchTable[0x2e].procp = smb_ReceiveV3ReadX;
smb_dispatchTable[0x2e].flags |= SMB_DISPATCHFLAG_CHAINED;
- smb_dispatchTable[0x32].procp = smb_ReceiveV3Tran2A; /* both are same */
+ smb_dispatchTable[0x32].procp = smb_ReceiveV3Tran2A; /* both are same */
smb_dispatchTable[0x32].flags |= SMB_DISPATCHFLAG_NORESPONSE;
smb_dispatchTable[0x33].procp = smb_ReceiveV3Tran2A;
smb_dispatchTable[0x33].flags |= SMB_DISPATCHFLAG_NORESPONSE;
smb_dispatchTable[0x34].procp = smb_ReceiveV3FindClose;
smb_dispatchTable[0x35].procp = smb_ReceiveV3FindNotifyClose;
- smb_dispatchTable[0x70].procp = smb_ReceiveCoreTreeConnect;
- smb_dispatchTable[0x71].procp = smb_ReceiveCoreTreeDisconnect;
- smb_dispatchTable[0x72].procp = smb_ReceiveNegotiate;
- smb_dispatchTable[0x73].procp = smb_ReceiveV3SessionSetupX;
+ smb_dispatchTable[0x70].procp = smb_ReceiveCoreTreeConnect;
+ smb_dispatchTable[0x71].procp = smb_ReceiveCoreTreeDisconnect;
+ smb_dispatchTable[0x72].procp = smb_ReceiveNegotiate;
+ smb_dispatchTable[0x73].procp = smb_ReceiveV3SessionSetupX;
smb_dispatchTable[0x73].flags |= SMB_DISPATCHFLAG_CHAINED;
smb_dispatchTable[0x74].procp = smb_ReceiveV3UserLogoffX;
smb_dispatchTable[0x74].flags |= SMB_DISPATCHFLAG_CHAINED;
smb_dispatchTable[0x75].procp = smb_ReceiveV3TreeConnectX;
smb_dispatchTable[0x75].flags |= SMB_DISPATCHFLAG_CHAINED;
- smb_dispatchTable[0x80].procp = smb_ReceiveCoreGetDiskAttributes;
- smb_dispatchTable[0x81].procp = smb_ReceiveCoreSearchDir;
- smb_dispatchTable[0xA0].procp = smb_ReceiveNTTransact;
- smb_dispatchTable[0xA2].procp = smb_ReceiveNTCreateX;
- smb_dispatchTable[0xA2].flags |= SMB_DISPATCHFLAG_CHAINED;
- smb_dispatchTable[0xA4].procp = smb_ReceiveNTCancel;
- smb_dispatchTable[0xA4].flags |= SMB_DISPATCHFLAG_NORESPONSE;
- smb_dispatchTable[0xc0].procp = smb_SendCoreBadOp;
- smb_dispatchTable[0xc1].procp = smb_SendCoreBadOp;
- smb_dispatchTable[0xc2].procp = smb_SendCoreBadOp;
- smb_dispatchTable[0xc3].procp = smb_SendCoreBadOp;
- for(i=0xd0; i<= 0xd7; i++) {
- smb_dispatchTable[i].procp = smb_SendCoreBadOp;
- }
-
- /* setup tran 2 dispatch table */
- smb_tran2DispatchTable[0].procp = smb_ReceiveTran2Open;
- smb_tran2DispatchTable[1].procp = smb_ReceiveTran2SearchDir; /* FindFirst */
- smb_tran2DispatchTable[2].procp = smb_ReceiveTran2SearchDir; /* FindNext */
- smb_tran2DispatchTable[3].procp = smb_ReceiveTran2QFSInfo;
- smb_tran2DispatchTable[4].procp = smb_ReceiveTran2SetFSInfo;
- smb_tran2DispatchTable[5].procp = smb_ReceiveTran2QPathInfo;
- smb_tran2DispatchTable[6].procp = smb_ReceiveTran2SetPathInfo;
- smb_tran2DispatchTable[7].procp = smb_ReceiveTran2QFileInfo;
- smb_tran2DispatchTable[8].procp = smb_ReceiveTran2SetFileInfo;
- smb_tran2DispatchTable[9].procp = smb_ReceiveTran2FSCTL;
- smb_tran2DispatchTable[10].procp = smb_ReceiveTran2IOCTL;
- smb_tran2DispatchTable[11].procp = smb_ReceiveTran2FindNotifyFirst;
- smb_tran2DispatchTable[12].procp = smb_ReceiveTran2FindNotifyNext;
- smb_tran2DispatchTable[13].procp = smb_ReceiveTran2MKDir;
+ smb_dispatchTable[0x80].procp = smb_ReceiveCoreGetDiskAttributes;
+ smb_dispatchTable[0x81].procp = smb_ReceiveCoreSearchDir;
+ smb_dispatchTable[0x82].procp = smb_SendCoreBadOp; /* Find */
+ smb_dispatchTable[0x83].procp = smb_SendCoreBadOp; /* Find Unique */
+ smb_dispatchTable[0x84].procp = smb_SendCoreBadOp; /* Find Close */
+ smb_dispatchTable[0xA0].procp = smb_ReceiveNTTransact;
+ smb_dispatchTable[0xA2].procp = smb_ReceiveNTCreateX;
+ smb_dispatchTable[0xA2].flags |= SMB_DISPATCHFLAG_CHAINED;
+ smb_dispatchTable[0xA4].procp = smb_ReceiveNTCancel;
+ smb_dispatchTable[0xA4].flags |= SMB_DISPATCHFLAG_NORESPONSE;
+ smb_dispatchTable[0xA5].procp = smb_ReceiveNTRename;
+ smb_dispatchTable[0xc0].procp = smb_SendCoreBadOp; /* Open Print File */
+ smb_dispatchTable[0xc1].procp = smb_SendCoreBadOp; /* Write Print File */
+ smb_dispatchTable[0xc2].procp = smb_SendCoreBadOp; /* Close Print File */
+ smb_dispatchTable[0xc3].procp = smb_SendCoreBadOp; /* Get Print Queue */
+ smb_dispatchTable[0xD8].procp = smb_SendCoreBadOp; /* Read Bulk */
+ smb_dispatchTable[0xD9].procp = smb_SendCoreBadOp; /* Write Bulk */
+ smb_dispatchTable[0xDA].procp = smb_SendCoreBadOp; /* Write Bulk Data */
+
+ /* setup tran 2 dispatch table */
+ smb_tran2DispatchTable[0].procp = smb_ReceiveTran2Open;
+ smb_tran2DispatchTable[1].procp = smb_ReceiveTran2SearchDir; /* FindFirst */
+ smb_tran2DispatchTable[2].procp = smb_ReceiveTran2SearchDir; /* FindNext */
+ smb_tran2DispatchTable[3].procp = smb_ReceiveTran2QFSInfo;
+ smb_tran2DispatchTable[4].procp = smb_ReceiveTran2SetFSInfo;
+ smb_tran2DispatchTable[5].procp = smb_ReceiveTran2QPathInfo;
+ smb_tran2DispatchTable[6].procp = smb_ReceiveTran2SetPathInfo;
+ smb_tran2DispatchTable[7].procp = smb_ReceiveTran2QFileInfo;
+ smb_tran2DispatchTable[8].procp = smb_ReceiveTran2SetFileInfo;
+ smb_tran2DispatchTable[9].procp = smb_ReceiveTran2FSCTL;
+ smb_tran2DispatchTable[10].procp = smb_ReceiveTran2IOCTL;
+ smb_tran2DispatchTable[11].procp = smb_ReceiveTran2FindNotifyFirst;
+ smb_tran2DispatchTable[12].procp = smb_ReceiveTran2FindNotifyNext;
+ smb_tran2DispatchTable[13].procp = smb_ReceiveTran2CreateDirectory;
+ smb_tran2DispatchTable[14].procp = smb_ReceiveTran2SessionSetup;
+ smb_tran2DispatchTable[14].procp = smb_ReceiveTran2GetDFSReferral;
+ smb_tran2DispatchTable[14].procp = smb_ReceiveTran2ReportDFSInconsistency;
/* setup the rap dispatch table */
memset(smb_rapDispatchTable, 0, sizeof(smb_rapDispatchTable));
smb_rapDispatchTable[63].procp = smb_ReceiveRAPNetWkstaGetInfo;
smb_rapDispatchTable[13].procp = smb_ReceiveRAPNetServerGetInfo;
- smb3_Init();
+ smb3_Init();
- /* if we are doing SMB authentication we have register outselves as a logon process */
- if (smb_authType != SMB_AUTH_NONE) {
+ /* if we are doing SMB authentication we have register outselves as a logon process */
+ if (smb_authType != SMB_AUTH_NONE) {
NTSTATUS nts;
- LSA_STRING afsProcessName;
- LSA_OPERATIONAL_MODE dummy; /*junk*/
-
- afsProcessName.Buffer = "OpenAFSClientDaemon";
- afsProcessName.Length = strlen(afsProcessName.Buffer);
- afsProcessName.MaximumLength = afsProcessName.Length + 1;
-
- nts = LsaRegisterLogonProcess(&afsProcessName, &smb_lsaHandle, &dummy);
-
- if (nts == STATUS_SUCCESS) {
- LSA_STRING packageName;
- /* we are registered. Find out the security package id */
- packageName.Buffer = MSV1_0_PACKAGE_NAME;
- packageName.Length = strlen(packageName.Buffer);
- packageName.MaximumLength = packageName.Length + 1;
- nts = LsaLookupAuthenticationPackage(smb_lsaHandle, &packageName , &smb_lsaSecPackage);
- if (nts == STATUS_SUCCESS) {
- smb_lsaLogonOrigin.Buffer = "OpenAFS";
- smb_lsaLogonOrigin.Length = strlen(smb_lsaLogonOrigin.Buffer);
- smb_lsaLogonOrigin.MaximumLength = smb_lsaLogonOrigin.Length + 1;
- } else {
- afsi_log("Can't determine security package name for NTLM!! NTSTATUS=[%l]",nts);
- }
- } else {
- afsi_log("Can't register logon process!! NTSTATUS=[%l]",nts);
- }
+ LSA_STRING afsProcessName;
+ LSA_OPERATIONAL_MODE dummy; /*junk*/
+
+ afsProcessName.Buffer = "OpenAFSClientDaemon";
+ afsProcessName.Length = strlen(afsProcessName.Buffer);
+ afsProcessName.MaximumLength = afsProcessName.Length + 1;
+
+ nts = LsaRegisterLogonProcess(&afsProcessName, &smb_lsaHandle, &dummy);
+
+ if (nts == STATUS_SUCCESS) {
+ LSA_STRING packageName;
+ /* we are registered. Find out the security package id */
+ packageName.Buffer = MSV1_0_PACKAGE_NAME;
+ packageName.Length = strlen(packageName.Buffer);
+ packageName.MaximumLength = packageName.Length + 1;
+ nts = LsaLookupAuthenticationPackage(smb_lsaHandle, &packageName , &smb_lsaSecPackage);
+ if (nts == STATUS_SUCCESS) {
+ smb_lsaLogonOrigin.Buffer = "OpenAFS";
+ smb_lsaLogonOrigin.Length = strlen(smb_lsaLogonOrigin.Buffer);
+ smb_lsaLogonOrigin.MaximumLength = smb_lsaLogonOrigin.Length + 1;
+ } else {
+ afsi_log("Can't determine security package name for NTLM!! NTSTATUS=[%l]",nts);
+ }
+ } else {
+ afsi_log("Can't register logon process!! NTSTATUS=[%l]",nts);
+ }
- if (nts != STATUS_SUCCESS) {
- /* something went wrong. We report the error and revert back to no authentication
- because we can't perform any auth requests without a successful lsa handle
- or sec package id. */
- afsi_log("Reverting to NO SMB AUTH");
- smb_authType = SMB_AUTH_NONE;
- }
+ if (nts != STATUS_SUCCESS) {
+ /* something went wrong. We report the error and revert back to no authentication
+ because we can't perform any auth requests without a successful lsa handle
+ or sec package id. */
+ afsi_log("Reverting to NO SMB AUTH");
+ smb_authType = SMB_AUTH_NONE;
+ }
#ifdef COMMENT
/* Don't fallback to SMB_AUTH_NTLM. Apparently, allowing SPNEGO to be used each
* time prevents the failure of authentication when logged into Windows with an
return name;
}
-#ifdef NOTSERVICE
+#ifdef LOG_PACKET
void smb_LogPacket(smb_packet_t *packet)
{
BYTE *vp, *cp;
*cp = 0;
- osi_Log0( smb_logp, buf );
+ osi_Log0( smb_logp, osi_LogSaveString(smb_logp, buf));
}
osi_Log0(smb_logp, "*** End SMB packet dump ***");
}
+#endif /* LOG_PACKET */
-#endif /* NOTSERVICE */
int smb_DumpVCP(FILE *outputFile, char *cookie)
{
unp = uidp->unp;
userp = unp->userp;
newUid = (unsigned short)uidp->userID; /* For some reason these are different types!*/
- osi_LogEvent("AFS smb_ReceiveV3SessionSetupX",NULL,"FindUserByName:Lana[%d],lsn[%d],userid[%d],name[%s]",vcp->lana,vcp->lsn,newUid,osi_LogSaveString(smb_logp, usern));
- osi_Log3(smb_logp,"smb_ReceiveV3SessionSetupX FindUserByName:Lana[%d],lsn[%d],userid[%d]",vcp->lana,vcp->lsn,newUid);
+ osi_LogEvent("AFS smb_ReceiveV3SessionSetupX",NULL,"FindUserByName:Lana[%d],lsn[%d],userid[%d],name[%s]",vcp->lana,vcp->lsn,newUid,osi_LogSaveString(smb_logp, usern));
+ osi_Log3(smb_logp,"smb_ReceiveV3SessionSetupX FindUserByName:Lana[%d],lsn[%d],userid[%d]",vcp->lana,vcp->lsn,newUid);
smb_ReleaseUID(uidp);
}
else {
uidp = smb_FindUID(vcp, newUid, SMB_FLAG_CREATE);
lock_ObtainMutex(&uidp->mx);
uidp->unp = unp;
- osi_LogEvent("AFS smb_ReceiveV3SessionSetupX",NULL,"MakeNewUser:VCP[%x],Lana[%d],lsn[%d],userid[%d],TicketKTCName[%s]",(int)vcp,vcp->lana,vcp->lsn,newUid,osi_LogSaveString(smb_logp, usern));
- osi_Log4(smb_logp,"smb_ReceiveV3SessionSetupX MakeNewUser:VCP[%x],Lana[%d],lsn[%d],userid[%d]",vcp,vcp->lana,vcp->lsn,newUid);
+ osi_LogEvent("AFS smb_ReceiveV3SessionSetupX",NULL,"MakeNewUser:VCP[%x],Lana[%d],lsn[%d],userid[%d],TicketKTCName[%s]",(int)vcp,vcp->lana,vcp->lsn,newUid,osi_LogSaveString(smb_logp, usern));
+ osi_Log4(smb_logp,"smb_ReceiveV3SessionSetupX MakeNewUser:VCP[%x],Lana[%d],lsn[%d],userid[%d]",vcp,vcp->lana,vcp->lsn,newUid);
lock_ReleaseMutex(&uidp->mx);
smb_ReleaseUID(uidp);
}
long smb_ReceiveV3UserLogoffX(smb_vc_t *vcp, smb_packet_t *inp, smb_packet_t *outp)
{
- smb_user_t *uidp;
+ smb_user_t *uidp;
- /* don't get tokens from this VC */
- vcp->flags |= SMB_VCFLAG_ALREADYDEAD;
+ /* don't get tokens from this VC */
+ vcp->flags |= SMB_VCFLAG_ALREADYDEAD;
- inp->flags |= SMB_PACKETFLAG_PROFILE_UPDATE_OK;
+ inp->flags |= SMB_PACKETFLAG_PROFILE_UPDATE_OK;
- /* find the tree and free it */
+ /* find the tree and free it */
uidp = smb_FindUID(vcp, ((smb_t *)inp)->uid, 0);
/* TODO: smb_ReleaseUID() ? */
if (uidp) {
- char *s1 = NULL, *s2 = NULL;
+ char *s1 = NULL, *s2 = NULL;
- if (s2 == NULL) s2 = " ";
- if (s1 == NULL) {s1 = s2; s2 = " ";}
+ if (s2 == NULL) s2 = " ";
+ if (s1 == NULL) {s1 = s2; s2 = " ";}
- osi_Log4(smb_logp, "SMB3 user logoffX uid %d name %s%s%s", uidp->userID,
- osi_LogSaveString(smb_logp, (uidp->unp) ? uidp->unp->name: " "), s1, s2);
+ osi_Log4(smb_logp, "SMB3 user logoffX uid %d name %s%s%s", uidp->userID,
+ osi_LogSaveString(smb_logp, (uidp->unp) ? uidp->unp->name: " "), s1, s2);
- lock_ObtainMutex(&uidp->mx);
- uidp->flags |= SMB_USERFLAG_DELETE;
- /*
- * it doesn't get deleted right away
- * because the vcp points to it
- */
+ lock_ObtainMutex(&uidp->mx);
+ uidp->flags |= SMB_USERFLAG_DELETE;
+ /*
+ * it doesn't get deleted right away
+ * because the vcp points to it
+ */
lock_ReleaseMutex(&uidp->mx);
}
- else
- osi_Log0(smb_logp, "SMB3 user logoffX");
+ else
+ osi_Log0(smb_logp, "SMB3 user logoffX");
smb_SetSMBDataLength(outp, 0);
return 0;
smb_user_t *uidp;
unsigned short newTid;
char shareName[256];
- char *sharePath;
- int shareFound;
+ char *sharePath;
+ int shareFound;
char *tp;
char *pathp;
char *passwordp;
- char *servicep;
+ char *servicep;
cm_user_t *userp;
- int ipc = 0;
+ int ipc = 0;
- osi_Log0(smb_logp, "SMB3 receive tree connect");
+ osi_Log0(smb_logp, "SMB3 receive tree connect");
- /* parse input parameters */
- tp = smb_GetSMBData(inp, NULL);
+ /* parse input parameters */
+ tp = smb_GetSMBData(inp, NULL);
passwordp = smb_ParseString(tp, &tp);
- pathp = smb_ParseString(tp, &tp);
- servicep = smb_ParseString(tp, &tp);
+ pathp = smb_ParseString(tp, &tp);
+ servicep = smb_ParseString(tp, &tp);
- tp = strrchr(pathp, '\\');
+ tp = strrchr(pathp, '\\');
if (!tp) {
return CM_ERROR_BADSMB;
}
strcpy(shareName, tp+1);
osi_Log2(smb_logp, "Tree connect pathp[%s] shareName[%s]",
- osi_LogSaveString(smb_logp, pathp),
- osi_LogSaveString(smb_logp, shareName));
+ osi_LogSaveString(smb_logp, pathp),
+ osi_LogSaveString(smb_logp, shareName));
- if (strcmp(servicep, "IPC") == 0 || strcmp(shareName, "IPC$") == 0) {
+ if (strcmp(servicep, "IPC") == 0 || strcmp(shareName, "IPC$") == 0) {
#ifndef NO_IPC
- osi_Log0(smb_logp, "TreeConnectX connecting to IPC$");
- ipc = 1;
+ osi_Log0(smb_logp, "TreeConnectX connecting to IPC$");
+ ipc = 1;
#else
- return CM_ERROR_NOIPC;
+ return CM_ERROR_NOIPC;
#endif
- }
+ }
userp = smb_GetUser(vcp, inp);
- lock_ObtainMutex(&vcp->mx);
+ lock_ObtainMutex(&vcp->mx);
newTid = vcp->tidCounter++;
- lock_ReleaseMutex(&vcp->mx);
+ lock_ReleaseMutex(&vcp->mx);
- tidp = smb_FindTID(vcp, newTid, SMB_FLAG_CREATE);
+ tidp = smb_FindTID(vcp, newTid, SMB_FLAG_CREATE);
- if(!ipc) {
- uidp = smb_FindUID(vcp, ((smb_t *)inp)->uid, 0);
+ if(!ipc) {
+ uidp = smb_FindUID(vcp, ((smb_t *)inp)->uid, 0);
shareFound = smb_FindShare(vcp, uidp, shareName, &sharePath);
- if (uidp)
- smb_ReleaseUID(uidp);
+ if (uidp)
+ smb_ReleaseUID(uidp);
if (!shareFound) {
- smb_ReleaseTID(tidp);
- return CM_ERROR_BADSHARENAME;
+ smb_ReleaseTID(tidp);
+ return CM_ERROR_BADSHARENAME;
}
if (vcp->flags & SMB_VCFLAG_USENT)
- {
- int policy = smb_FindShareCSCPolicy(shareName);
- smb_SetSMBParm(outp, 2, SMB_SUPPORT_SEARCH_BITS | (policy << 2));
+ {
+ int policy = smb_FindShareCSCPolicy(shareName);
+ smb_SetSMBParm(outp, 2, SMB_SUPPORT_SEARCH_BITS | (policy << 2));
+ }
+ } else {
+ smb_SetSMBParm(outp, 2, 0);
+ sharePath = NULL;
}
- } else {
- smb_SetSMBParm(outp, 2, 0);
- sharePath = NULL;
- }
lock_ObtainMutex(&tidp->mx);
tidp->userp = userp;
- tidp->pathname = sharePath;
- if(ipc) tidp->flags |= SMB_TIDFLAG_IPC;
+ tidp->pathname = sharePath;
+ if(ipc) tidp->flags |= SMB_TIDFLAG_IPC;
lock_ReleaseMutex(&tidp->mx);
smb_ReleaseTID(tidp);
- ((smb_t *)outp)->tid = newTid;
- ((smb_t *)inp)->tid = newTid;
- tp = smb_GetSMBData(outp, NULL);
- if(!ipc) {
- *tp++ = 'A';
- *tp++ = ':';
- *tp++ = 0;
- smb_SetSMBDataLength(outp, 3);
- } else {
- strcpy(tp, "IPC");
- smb_SetSMBDataLength(outp, 4);
- }
+ ((smb_t *)outp)->tid = newTid;
+ ((smb_t *)inp)->tid = newTid;
+ tp = smb_GetSMBData(outp, NULL);
+ if (!ipc) {
+ *tp++ = 'A';
+ *tp++ = ':';
+ *tp++ = 0;
+ smb_SetSMBDataLength(outp, 3);
+ } else {
+ strcpy(tp, "IPC");
+ smb_SetSMBDataLength(outp, 4);
+ }
osi_Log1(smb_logp, "SMB3 tree connect created ID %d", newTid);
return 0;
/* must be called with global tran lock held */
smb_tran2Packet_t *smb_FindTran2Packet(smb_vc_t *vcp, smb_packet_t *inp)
{
- smb_tran2Packet_t *tp;
+ smb_tran2Packet_t *tp;
smb_t *smbp;
smbp = (smb_t *) inp->data;
- for(tp = smb_tran2AssemblyQueuep; tp; tp = (smb_tran2Packet_t *) osi_QNext(&tp->q)) {
- if (tp->vcp == vcp && tp->mid == smbp->mid && tp->tid == smbp->tid)
+ for (tp = smb_tran2AssemblyQueuep; tp; tp = (smb_tran2Packet_t *) osi_QNext(&tp->q)) {
+ if (tp->vcp == vcp && tp->mid == smbp->mid && tp->tid == smbp->tid)
return tp;
}
return NULL;
smb_tran2Packet_t *smb_NewTran2Packet(smb_vc_t *vcp, smb_packet_t *inp,
int totalParms, int totalData)
{
- smb_tran2Packet_t *tp;
+ smb_tran2Packet_t *tp;
smb_t *smbp;
smbp = (smb_t *) inp->data;
- tp = malloc(sizeof(*tp));
+ tp = malloc(sizeof(*tp));
memset(tp, 0, sizeof(*tp));
tp->vcp = vcp;
smb_HoldVC(vcp);
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);
- if (totalParms != 0)
+ tp->res[0] = smbp->res[0];
+ osi_QAdd((osi_queue_t **)&smb_tran2AssemblyQueuep, &tp->q);
+ if (totalParms != 0)
tp->parmsp = malloc(totalParms);
- if (totalData != 0)
+ if (totalData != 0)
tp->datap = malloc(totalData);
- if (smbp->com == 0x25 || smbp->com == 0x26)
- tp->com = 0x25;
- else {
- tp->opcode = smb_GetSMBParm(inp, 14);
- tp->com = 0x32;
- }
- tp->flags |= SMB_TRAN2PFLAG_ALLOC;
+ if (smbp->com == 0x25 || smbp->com == 0x26)
+ tp->com = 0x25;
+ else {
+ tp->opcode = smb_GetSMBParm(inp, 14);
+ tp->com = 0x32;
+ }
+ tp->flags |= SMB_TRAN2PFLAG_ALLOC;
return tp;
}
smb_tran2Packet_t *smb_GetTran2ResponsePacket(smb_vc_t *vcp,
- smb_tran2Packet_t *inp, smb_packet_t *outp,
- int totalParms, int totalData)
+ smb_tran2Packet_t *inp, smb_packet_t *outp,
+ int totalParms, int totalData)
{
- smb_tran2Packet_t *tp;
- unsigned short parmOffset;
- unsigned short dataOffset;
- unsigned short dataAlign;
+ smb_tran2Packet_t *tp;
+ unsigned short parmOffset;
+ unsigned short dataOffset;
+ unsigned short dataAlign;
- tp = malloc(sizeof(*tp));
+ tp = malloc(sizeof(*tp));
memset(tp, 0, sizeof(*tp));
tp->vcp = NULL;
tp->curData = tp->curParms = 0;
tp->totalData = totalData;
tp->totalParms = totalParms;
- tp->oldTotalParms = totalParms;
+ tp->oldTotalParms = totalParms;
tp->tid = inp->tid;
tp->mid = inp->mid;
tp->uid = inp->uid;
tp->pid = inp->pid;
- tp->res[0] = inp->res[0];
+ tp->res[0] = inp->res[0];
tp->opcode = inp->opcode;
- tp->com = inp->com;
+ tp->com = inp->com;
- /*
- * We calculate where the parameters and data will start.
- * This calculation must parallel the calculation in
- * smb_SendTran2Packet.
- */
+ /*
+ * We calculate where the parameters and data will start.
+ * This calculation must parallel the calculation in
+ * smb_SendTran2Packet.
+ */
- parmOffset = 10*2 + 35;
- parmOffset++; /* round to even */
- tp->parmsp = (unsigned short *) (outp->data + parmOffset);
+ parmOffset = 10*2 + 35;
+ parmOffset++; /* round to even */
+ tp->parmsp = (unsigned short *) (outp->data + parmOffset);
- dataOffset = parmOffset + totalParms;
- dataAlign = dataOffset & 2; /* quad-align */
- dataOffset += dataAlign;
- tp->datap = outp->data + dataOffset;
+ dataOffset = parmOffset + totalParms;
+ dataAlign = dataOffset & 2; /* quad-align */
+ dataOffset += dataAlign;
+ tp->datap = outp->data + dataOffset;
return tp;
-}
+}
/* free a tran2 packet; must be called with smb_globalLock held */
void smb_FreeTran2Packet(smb_tran2Packet_t *t2p)
code = CM_ERROR_BADOP;
}
- /* if an error is returned, we're supposed to send an error packet,
+ /* 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.
smb_SendTran2Error(vcp, asp, outp, code);
}
- /* free the input tran 2 packet */
- lock_ObtainWrite(&smb_globalLock);
+ /* free the input tran 2 packet */
+ lock_ObtainWrite(&smb_globalLock);
smb_FreeTran2Packet(asp);
- lock_ReleaseWrite(&smb_globalLock);
+ lock_ReleaseWrite(&smb_globalLock);
}
else if (firstPacket) {
- /* the first packet in a multi-packet request, we need to send an
+ /* 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);
}
- return 0;
+ return 0;
}
/* ANSI versions. The unicode versions support arbitrary length
long smb_ReceiveTran2Open(smb_vc_t *vcp, smb_tran2Packet_t *p, smb_packet_t *op)
{
- char *pathp;
+ char *pathp;
smb_tran2Packet_t *outp;
long code = 0;
- cm_space_t *spacep;
+ cm_space_t *spacep;
int excl;
cm_user_t *userp;
cm_scache_t *dscp; /* dir we're dealing with */
int openAction;
int parmSlot; /* which parm we're dealing with */
long returnEALength;
- char *tidPathp;
- cm_req_t req;
+ char *tidPathp;
+ cm_req_t req;
- cm_InitReq(&req);
+ cm_InitReq(&req);
scp = NULL;
- extraInfo = (p->parmsp[0] & 1); /* return extra info */
+ extraInfo = (p->parmsp[0] & 1); /* return extra info */
returnEALength = (p->parmsp[0] & 8); /* return extended attr length */
- openFun = p->parmsp[6]; /* open function */
+ openFun = p->parmsp[6]; /* open function */
excl = ((openFun & 3) == 0);
trunc = ((openFun & 3) == 2); /* truncate it */
- openMode = (p->parmsp[1] & 0x7);
+ openMode = (p->parmsp[1] & 0x7);
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 */
+ /* compute initial mode bits based on read-only flag in attributes */
initialModeBits = 0666;
if (attributes & 1) initialModeBits &= ~0222;
outp = smb_GetTran2ResponsePacket(vcp, p, op, 40, 0);
- spacep = cm_GetSpace();
+ spacep = cm_GetSpace();
smb_StripLastComponent(spacep->data, &lastNamep, pathp);
- if (lastNamep && strcmp(lastNamep, SMB_IOCTL_FILENAME) == 0) {
- /* special case magic file name for receiving IOCTL requests
+ 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);
/* copy out remainder of the parms */
- parmSlot = 0;
- outp->parmsp[parmSlot] = fidp->fid; parmSlot++;
- if (extraInfo) {
+ 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] = 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 */
+ }
+ /* and the final "always present" stuff */
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++;
+ /* next write out the "unique" ID */
+ outp->parmsp[parmSlot] = 0x1234; parmSlot++;
+ outp->parmsp[parmSlot] = 0x5678; parmSlot++;
outp->parmsp[parmSlot] = 0; parmSlot++;
- if (returnEALength) {
- 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_FreeTran2Packet(outp);
- /* and clean up fid reference */
+ /* and clean up fid reference */
smb_ReleaseFID(fidp);
return 0;
}
#ifdef DEBUG_VERBOSE
- {
- char *hexp, *asciip;
- asciip = (lastNamep ? lastNamep : pathp);
- hexp = osi_HexifyString( asciip );
- DEBUG_EVENT2("AFS","T2Open H[%s] A[%s]", hexp, asciip);
- free(hexp);
- }
+ {
+ char *hexp, *asciip;
+ asciip = (lastNamep ? lastNamep : pathp);
+ hexp = osi_HexifyString( asciip );
+ DEBUG_EVENT2("AFS","T2Open H[%s] A[%s]", hexp, asciip);
+ free(hexp);
+ }
#endif
- userp = smb_GetTran2User(vcp, p);
+ userp = smb_GetTran2User(vcp, p);
/* In the off chance that userp is NULL, we log and abandon */
if (!userp) {
osi_Log1(smb_logp, "ReceiveTran2Open user [%d] not resolvable", p->uid);
return CM_ERROR_BADSMB;
}
- code = smb_LookupTIDPath(vcp, p->tid, &tidPathp);
- if(code == CM_ERROR_TIDIPC) {
+ 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. */
return CM_ERROR_NOSUCHPATH;
}
- dscp = NULL;
- code = cm_NameI(cm_rootSCachep, pathp,
- 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_FreeSpace(spacep);
+ dscp = NULL;
+ code = cm_NameI(cm_rootSCachep, pathp,
+ 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_FreeSpace(spacep);
if (code) {
cm_ReleaseUser(userp);
- smb_FreeTran2Packet(outp);
+ 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.
+ * and truncate the file if we find it, otherwise we create the
+ * file.
*/
- if (!lastNamep) lastNamep = pathp;
- else lastNamep++;
+ 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_ReleaseSCache(dscp);
cm_ReleaseUser(userp);
- smb_FreeTran2Packet(outp);
+ smb_FreeTran2Packet(outp);
return code;
}
- }
+ }
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 (code == 0) {
+ if (code == 0) {
code = cm_CheckOpen(scp, openMode, trunc, userp, &req);
if (code) {
if (dscp) cm_ReleaseSCache(dscp);
cm_ReleaseSCache(scp);
cm_ReleaseUser(userp);
- smb_FreeTran2Packet(outp);
+ smb_FreeTran2Packet(outp);
return code;
}
- if (excl) {
- /* oops, file shouldn't be there */
+ if (excl) {
+ /* oops, file shouldn't be there */
if (dscp) cm_ReleaseSCache(dscp);
cm_ReleaseSCache(scp);
cm_ReleaseUser(userp);
- smb_FreeTran2Packet(outp);
+ smb_FreeTran2Packet(outp);
return CM_ERROR_EXISTS;
}
- if (trunc) {
- setAttr.mask = CM_ATTRMASK_LENGTH;
+ if (trunc) {
+ setAttr.mask = CM_ATTRMASK_LENGTH;
setAttr.length.LowPart = 0;
setAttr.length.HighPart = 0;
- code = cm_SetAttr(scp, &setAttr, userp, &req);
+ code = cm_SetAttr(scp, &setAttr, userp, &req);
openAction = 3; /* truncated existing file */
- }
- else openAction = 1; /* found existing file */
+ }
+ else
+ openAction = 1; /* found existing file */
}
- else if (!(openFun & SMB_ATTR_DIRECTORY)) {
- /* don't create if not found */
+ else if (!(openFun & SMB_ATTR_DIRECTORY)) {
+ /* don't create if not found */
if (dscp) cm_ReleaseSCache(dscp);
osi_assert(scp == NULL);
cm_ReleaseUser(userp);
- smb_FreeTran2Packet(outp);
+ smb_FreeTran2Packet(outp);
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);
+ 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);
- if (code == 0 && (dscp->flags & CM_SCACHEFLAG_ANYWATCH))
- smb_NotifyChange(FILE_ACTION_ADDED,
+ &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) {
- /* 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.
+ /* 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);
+ userp, &req, &scp);
if (code == 0) {
if (trunc) {
- setAttr.mask = CM_ATTRMASK_LENGTH;
+ setAttr.mask = CM_ATTRMASK_LENGTH;
setAttr.length.LowPart = 0;
setAttr.length.HighPart = 0;
code = cm_SetAttr(scp, &setAttr, userp,
- &req);
+ &req);
}
- } /* lookup succeeded */
+ } /* lookup succeeded */
}
}
- /* we don't need this any longer */
- if (dscp) cm_ReleaseSCache(dscp);
+ /* we don't need this any longer */
+ if (dscp) cm_ReleaseSCache(dscp);
if (code) {
- /* something went wrong creating or truncating the file */
+ /* something went wrong creating or truncating the file */
if (scp) cm_ReleaseSCache(scp);
cm_ReleaseUser(userp);
- smb_FreeTran2Packet(outp);
+ smb_FreeTran2Packet(outp);
return code;
}
- /* make sure we're about to open a file */
- if (scp->fileType != CM_SCACHETYPE_FILE) {
- cm_ReleaseSCache(scp);
- cm_ReleaseUser(userp);
- smb_FreeTran2Packet(outp);
- return CM_ERROR_ISDIR;
- }
+ /* make sure we're about to open a file */
+ if (scp->fileType != CM_SCACHETYPE_FILE) {
+ code = 0;
+ while (code == 0 && scp->fileType == CM_SCACHETYPE_SYMLINK) {
+ cm_scache_t * targetScp = 0;
+ code = cm_EvaluateSymLink(dscp, scp, &targetScp, userp, &req);
+ if (code == 0) {
+ /* we have a more accurate file to use (the
+ * target of the symbolic link). Otherwise,
+ * we'll just use the symlink anyway.
+ */
+ osi_Log2(smb_logp, "symlink vp %x to vp %x",
+ scp, targetScp);
+ cm_ReleaseSCache(scp);
+ scp = targetScp;
+ }
+ }
+ if (scp->fileType != CM_SCACHETYPE_FILE) {
+ cm_ReleaseSCache(scp);
+ cm_ReleaseUser(userp);
+ smb_FreeTran2Packet(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);
- /* save a pointer to the vnode */
+ /* save a pointer to the vnode */
fidp->scp = scp;
- /* compute open mode */
+ /* compute open mode */
if (openMode != 1) fidp->flags |= SMB_FID_OPENREAD;
if (openMode == 1 || openMode == 2)
fidp->flags |= SMB_FID_OPENWRITE;
- smb_ReleaseFID(fidp);
+ smb_ReleaseFID(fidp);
- cm_Open(scp, 0, userp);
+ cm_Open(scp, 0, userp);
/* copy out remainder of the parms */
- parmSlot = 0;
- outp->parmsp[parmSlot] = fidp->fid; parmSlot++;
- lock_ObtainMutex(&scp->mx);
- if (extraInfo) {
+ parmSlot = 0;
+ outp->parmsp[parmSlot] = fidp->fid; parmSlot++;
+ lock_ObtainMutex(&scp->mx);
+ if (extraInfo) {
outp->parmsp[parmSlot] = smb_Attributes(scp); parmSlot++;
- smb_SearchTimeFromUnixTime(&dosTime, scp->clientModTime);
+ smb_SearchTimeFromUnixTime(&dosTime, scp->clientModTime);
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);
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 */
+ }
+ /* and the final "always present" stuff */
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++;
+ /* 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++;
- outp->parmsp[parmSlot] = 0; parmSlot++;
- }
- lock_ReleaseMutex(&scp->mx);
- outp->totalData = 0; /* total # of data bytes */
+ 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 */
- smb_SendTran2Packet(vcp, outp, op);
-
+ smb_SendTran2Packet(vcp, outp, op);
+
smb_FreeTran2Packet(outp);
cm_ReleaseUser(userp);
long smb_ReceiveTran2FindFirst(smb_vc_t *vcp, smb_tran2Packet_t *p, smb_packet_t *outp)
{
+ osi_Log0(smb_logp,"ReceiveTran2FindFirst - NOT_SUPPORTED");
return CM_ERROR_BADOP;
}
long smb_ReceiveTran2FindNext(smb_vc_t *vcp, smb_tran2Packet_t *p, smb_packet_t *outp)
{
+ osi_Log0(smb_logp,"ReceiveTran2FindNext - NOT_SUPPORTED");
return CM_ERROR_BADOP;
}
long smb_ReceiveTran2QFSInfo(smb_vc_t *vcp, smb_tran2Packet_t *p, smb_packet_t *op)
{
- smb_tran2Packet_t *outp;
+ smb_tran2Packet_t *outp;
smb_tran2QFSInfo_t qi;
- int responseSize;
- osi_hyper_t temp;
- static char FSname[6] = {'A', 0, 'F', 0, 'S', 0};
+ int responseSize;
+ osi_hyper_t temp;
+ static char FSname[6] = {'A', 0, 'F', 0, 'S', 0};
- osi_Log1(smb_logp, "T2 QFSInfo type 0x%x", p->parmsp[0]);
-
- switch (p->parmsp[0]) {
- case 1: responseSize = sizeof(qi.u.allocInfo); break;
- case 2: responseSize = sizeof(qi.u.volumeInfo); break;
- case 0x102: responseSize = sizeof(qi.u.FSvolumeInfo); break;
- case 0x103: responseSize = sizeof(qi.u.FSsizeInfo); break;
- case 0x104: responseSize = sizeof(qi.u.FSdeviceInfo); break;
- case 0x105: responseSize = sizeof(qi.u.FSattributeInfo); break;
- default: return CM_ERROR_INVAL;
- }
+ osi_Log1(smb_logp, "T2 QFSInfo type 0x%x", p->parmsp[0]);
+
+ switch (p->parmsp[0]) {
+ case 1: responseSize = sizeof(qi.u.allocInfo); break;
+ case 2: responseSize = sizeof(qi.u.volumeInfo); break;
+ case 0x102: responseSize = sizeof(qi.u.FSvolumeInfo); break;
+ case 0x103: responseSize = sizeof(qi.u.FSsizeInfo); break;
+ case 0x104: responseSize = sizeof(qi.u.FSdeviceInfo); break;
+ case 0x105: responseSize = sizeof(qi.u.FSattributeInfo); break;
+ default: return CM_ERROR_INVAL;
+ }
outp = smb_GetTran2ResponsePacket(vcp, p, op, 0, responseSize);
- switch (p->parmsp[0]) {
- case 1:
- /* alloc info */
+ switch (p->parmsp[0]) {
+ case 1:
+ /* alloc info */
qi.u.allocInfo.FSID = 0;
qi.u.allocInfo.sectorsPerAllocUnit = 1;
qi.u.allocInfo.totalAllocUnits = 0x7fffffff;
qi.u.allocInfo.availAllocUnits = 0x3fffffff;
qi.u.allocInfo.bytesPerSector = 1024;
- break;
+ break;
case 2:
- /* volume info */
+ /* volume info */
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));
+ /* 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);
- break;
-
- case 0x102:
- /* FS volume info */
- memset((char *)&qi.u.FSvolumeInfo.vct, 0, sizeof(FILETIME));
- qi.u.FSvolumeInfo.vsn = 1234;
- qi.u.FSvolumeInfo.vnCount = 8;
- memcpy(qi.u.FSvolumeInfo.label, "A\0F\0S\0\0", 8);
- break;
-
- case 0x103:
- /* FS size info */
- temp.HighPart = 0;
- temp.LowPart = 0x7fffffff;
- qi.u.FSsizeInfo.totalAllocUnits = temp;
- temp.LowPart = 0x3fffffff;
- qi.u.FSsizeInfo.availAllocUnits = temp;
- qi.u.FSsizeInfo.sectorsPerAllocUnit = 1;
- qi.u.FSsizeInfo.bytesPerSector = 1024;
- break;
-
- case 0x104:
- /* FS device info */
- qi.u.FSdeviceInfo.devType = 0; /* don't have a number */
- qi.u.FSdeviceInfo.characteristics = 0x50; /* remote, virtual */
- break;
+ break;
+
+ case 0x102:
+ /* FS volume info */
+ memset((char *)&qi.u.FSvolumeInfo.vct, 0, sizeof(FILETIME));
+ qi.u.FSvolumeInfo.vsn = 1234;
+ qi.u.FSvolumeInfo.vnCount = 8;
+ memcpy(qi.u.FSvolumeInfo.label, "A\0F\0S\0\0", 8);
+ break;
+
+ case 0x103:
+ /* FS size info */
+ temp.HighPart = 0;
+ temp.LowPart = 0x7fffffff;
+ qi.u.FSsizeInfo.totalAllocUnits = temp;
+ temp.LowPart = 0x3fffffff;
+ qi.u.FSsizeInfo.availAllocUnits = temp;
+ qi.u.FSsizeInfo.sectorsPerAllocUnit = 1;
+ qi.u.FSsizeInfo.bytesPerSector = 1024;
+ break;
+
+ case 0x104:
+ /* FS device info */
+ qi.u.FSdeviceInfo.devType = 0; /* don't have a number */
+ qi.u.FSdeviceInfo.characteristics = 0x50; /* remote, virtual */
+ break;
case 0x105:
- /* FS attribute info */
- /* attributes, defined in WINNT.H:
- * FILE_CASE_SENSITIVE_SEARCH 0x1
- * FILE_CASE_PRESERVED_NAMES 0x2
- * <no name defined> 0x4000
- * If bit 0x4000 is not set, Windows 95 thinks
- * we can't handle long (non-8.3) names,
- * despite our protestations to the contrary.
- */
- qi.u.FSattributeInfo.attributes = 0x4003;
- qi.u.FSattributeInfo.maxCompLength = 255;
- qi.u.FSattributeInfo.FSnameLength = 6;
- memcpy(qi.u.FSattributeInfo.FSname, FSname, 6);
- break;
- }
+ /* FS attribute info */
+ /* attributes, defined in WINNT.H:
+ * FILE_CASE_SENSITIVE_SEARCH 0x1
+ * FILE_CASE_PRESERVED_NAMES 0x2
+ * <no name defined> 0x4000
+ * If bit 0x4000 is not set, Windows 95 thinks
+ * we can't handle long (non-8.3) names,
+ * despite our protestations to the contrary.
+ */
+ qi.u.FSattributeInfo.attributes = 0x4003;
+ qi.u.FSattributeInfo.maxCompLength = 255;
+ qi.u.FSattributeInfo.FSnameLength = 6;
+ memcpy(qi.u.FSattributeInfo.FSname, FSname, 6);
+ break;
+ }
- /* copy out return data, and set corresponding sizes */
- outp->totalParms = 0;
+ /* copy out return data, and set corresponding sizes */
+ outp->totalParms = 0;
outp->totalData = responseSize;
memcpy(outp->datap, &qi, responseSize);
- /* send and free the packets */
- smb_SendTran2Packet(vcp, outp, op);
+ /* send and free the packets */
+ smb_SendTran2Packet(vcp, outp, op);
smb_FreeTran2Packet(outp);
return 0;
long smb_ReceiveTran2SetFSInfo(smb_vc_t *vcp, smb_tran2Packet_t *p, smb_packet_t *outp)
{
+ osi_Log0(smb_logp,"ReceiveTran2SetFSInfo - NOT_SUPPORTED");
return CM_ERROR_BADOP;
}
struct smb_ShortNameRock {
- char *maskp;
- unsigned int vnode;
- char *shortName;
- size_t shortNameLen;
-};
+ char *maskp;
+ unsigned int vnode;
+ char *shortName;
+ size_t shortNameLen;
+};
int cm_GetShortNameProc(cm_scache_t *scp, cm_dirEntry_t *dep, void *vrockp,
- osi_hyper_t *offp)
-{
- struct smb_ShortNameRock *rockp;
- char *shortNameEnd;
-
- rockp = vrockp;
- /* compare both names and vnodes, though probably just comparing vnodes
- * would be safe enough.
- */
- if (cm_stricmp(dep->name, rockp->maskp) != 0)
- return 0;
- if (ntohl(dep->fid.vnode) != rockp->vnode)
- return 0;
- /* This is the entry */
- cm_Gen8Dot3Name(dep, rockp->shortName, &shortNameEnd);
- rockp->shortNameLen = shortNameEnd - rockp->shortName;
- return CM_ERROR_STOPNOW;
-}
+ osi_hyper_t *offp)
+{
+ struct smb_ShortNameRock *rockp;
+ char *shortNameEnd;
+
+ rockp = vrockp;
+ /* compare both names and vnodes, though probably just comparing vnodes
+ * would be safe enough.
+ */
+ if (cm_stricmp(dep->name, rockp->maskp) != 0)
+ return 0;
+ if (ntohl(dep->fid.vnode) != rockp->vnode)
+ return 0;
+ /* This is the entry */
+ cm_Gen8Dot3Name(dep, rockp->shortName, &shortNameEnd);
+ rockp->shortNameLen = shortNameEnd - rockp->shortName;
+ return CM_ERROR_STOPNOW;
+}
long cm_GetShortName(char *pathp, cm_user_t *userp, cm_req_t *reqp,
char *tidPathp, int vnode, char *shortName, size_t *shortNameLenp)
{
- struct smb_ShortNameRock rock;
- char *lastNamep;
- cm_space_t *spacep;
- cm_scache_t *dscp;
- int caseFold = CM_FLAG_FOLLOW | CM_FLAG_CASEFOLD;
- long code = 0;
- osi_hyper_t thyper;
+ struct smb_ShortNameRock rock;
+ char *lastNamep;
+ cm_space_t *spacep;
+ cm_scache_t *dscp;
+ int caseFold = CM_FLAG_FOLLOW | CM_FLAG_CASEFOLD;
+ long code = 0;
+ osi_hyper_t thyper;
- spacep = cm_GetSpace();
- smb_StripLastComponent(spacep->data, &lastNamep, pathp);
+ spacep = cm_GetSpace();
+ smb_StripLastComponent(spacep->data, &lastNamep, pathp);
- code = cm_NameI(cm_rootSCachep, spacep->data, caseFold, userp, tidPathp,
+ code = cm_NameI(cm_rootSCachep, spacep->data, caseFold, userp, tidPathp,
reqp, &dscp);
- cm_FreeSpace(spacep);
- if (code) return code;
-
- if (!lastNamep) lastNamep = pathp;
- else lastNamep++;
- thyper.LowPart = 0;
- thyper.HighPart = 0;
- rock.shortName = shortName;
- rock.vnode = vnode;
- rock.maskp = lastNamep;
- code = cm_ApplyDir(dscp, cm_GetShortNameProc, &rock, &thyper, userp,
+ cm_FreeSpace(spacep);
+ if (code) return code;
+
+ if (!lastNamep) lastNamep = pathp;
+ else lastNamep++;
+ thyper.LowPart = 0;
+ thyper.HighPart = 0;
+ rock.shortName = shortName;
+ rock.vnode = vnode;
+ rock.maskp = lastNamep;
+ code = cm_ApplyDir(dscp, cm_GetShortNameProc, &rock, &thyper, userp,
reqp, NULL);
- cm_ReleaseSCache(dscp);
+ cm_ReleaseSCache(dscp);
- if (code == 0)
- return CM_ERROR_NOSUCHFILE;
- if (code == CM_ERROR_STOPNOW) {
- *shortNameLenp = rock.shortNameLen;
- return 0;
- }
- return code;
+ if (code == 0)
+ return CM_ERROR_NOSUCHFILE;
+ if (code == CM_ERROR_STOPNOW) {
+ *shortNameLenp = rock.shortNameLen;
+ return 0;
+ }
+ return code;
}
long smb_ReceiveTran2QPathInfo(smb_vc_t *vcp, smb_tran2Packet_t *p, smb_packet_t *opx)
{
- smb_tran2Packet_t *outp;
+ smb_tran2Packet_t *outp;
time_t dosTime;
- FILETIME ft;
+ FILETIME ft;
unsigned short infoLevel;
int nbytesRequired;
unsigned short attributes;
- unsigned long extAttributes;
- char shortName[13];
- unsigned int len;
+ unsigned long extAttributes;
+ char shortName[13];
+ unsigned int len;
cm_user_t *userp;
- cm_space_t *spacep;
+ cm_space_t *spacep;
cm_scache_t *scp, *dscp;
long code = 0;
char *op;
- char *tidPathp;
- char *lastComp;
- cm_req_t req;
+ char *tidPathp;
+ char *lastComp;
+ cm_req_t req;
- cm_InitReq(&req);
+ cm_InitReq(&req);
- infoLevel = p->parmsp[0];
+ infoLevel = p->parmsp[0];
if (infoLevel == 6) nbytesRequired = 0;
else if (infoLevel == 1) nbytesRequired = 22;
else if (infoLevel == 2) nbytesRequired = 26;
- else if (infoLevel == 0x101) nbytesRequired = 40;
- else if (infoLevel == 0x102) nbytesRequired = 24;
- else if (infoLevel == 0x103) nbytesRequired = 4;
- else if (infoLevel == 0x108) nbytesRequired = 30;
+ else if (infoLevel == 0x101) nbytesRequired = 40;
+ else if (infoLevel == 0x102) nbytesRequired = 24;
+ else if (infoLevel == 0x103) nbytesRequired = 4;
+ else if (infoLevel == 0x108) nbytesRequired = 30;
else {
- osi_Log2(smb_logp, "Bad Tran2 op 0x%x infolevel 0x%x",
+ osi_Log2(smb_logp, "Bad Tran2 op 0x%x infolevel 0x%x",
p->opcode, infoLevel);
- smb_SendTran2Error(vcp, p, opx, CM_ERROR_INVAL);
+ smb_SendTran2Error(vcp, p, opx, CM_ERROR_INVAL);
return 0;
}
- osi_Log2(smb_logp, "T2 QPathInfo type 0x%x path %s", infoLevel,
- osi_LogSaveString(smb_logp, (char *)(&p->parmsp[3])));
+ osi_Log2(smb_logp, "T2 QPathInfo type 0x%x path %s", infoLevel,
+ osi_LogSaveString(smb_logp, (char *)(&p->parmsp[3])));
outp = smb_GetTran2ResponsePacket(vcp, p, opx, 2, nbytesRequired);
- if (infoLevel > 0x100)
- outp->totalParms = 2;
- else
- outp->totalParms = 0;
- outp->totalData = nbytesRequired;
+ if (infoLevel > 0x100)
+ outp->totalParms = 2;
+ else
+ outp->totalParms = 0;
+ outp->totalData = nbytesRequired;
/* now, if we're at infoLevel 6, we're only being asked to check
* the syntax, so we just OK things now. In particular, we're *not*
* being asked to verify anything about the state of any parent dirs.
*/
- if (infoLevel == 6) {
- smb_SendTran2Packet(vcp, outp, opx);
+ if (infoLevel == 6) {
+ smb_SendTran2Packet(vcp, outp, opx);
smb_FreeTran2Packet(outp);
- return 0;
- }
+ return 0;
+ }
userp = smb_GetTran2User(vcp, p);
if (!userp) {
return CM_ERROR_BADSMB;
}
- code = smb_LookupTIDPath(vcp, p->tid, &tidPathp);
+ code = smb_LookupTIDPath(vcp, p->tid, &tidPathp);
if(code) {
cm_ReleaseUser(userp);
smb_SendTran2Error(vcp, p, opx, CM_ERROR_NOSUCHPATH);
return 0;
}
- /*
- * XXX Strange hack XXX
- *
- * As of Patch 7 (13 January 98), we are having the following problem:
- * In NT Explorer 4.0, whenever we click on a directory, AFS gets
- * requests to look up "desktop.ini" in all the subdirectories.
- * This can cause zillions of timeouts looking up non-existent cells
- * and volumes, especially in the top-level directory.
- *
- * We have not found any way to avoid this or work around it except
- * to explicitly ignore the requests for mount points that haven't
- * yet been evaluated and for directories that haven't yet been
- * fetched.
- */
- if (infoLevel == 0x101) {
- spacep = cm_GetSpace();
- smb_StripLastComponent(spacep->data, &lastComp,
- (char *)(&p->parmsp[3]));
- /* Make sure that lastComp is not NULL */
- if (lastComp) {
- if (strcmp(lastComp, "\\desktop.ini") == 0) {
+ /*
+ * XXX Strange hack XXX
+ *
+ * As of Patch 7 (13 January 98), we are having the following problem:
+ * In NT Explorer 4.0, whenever we click on a directory, AFS gets
+ * requests to look up "desktop.ini" in all the subdirectories.
+ * This can cause zillions of timeouts looking up non-existent cells
+ * and volumes, especially in the top-level directory.
+ *
+ * We have not found any way to avoid this or work around it except
+ * to explicitly ignore the requests for mount points that haven't
+ * yet been evaluated and for directories that haven't yet been
+ * fetched.
+ */
+ if (infoLevel == 0x101) {
+ spacep = cm_GetSpace();
+ smb_StripLastComponent(spacep->data, &lastComp,
+ (char *)(&p->parmsp[3]));
+ /* 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);
+ CM_FLAG_CASEFOLD
+ | CM_FLAG_DIRSEARCH
+ | CM_FLAG_FOLLOW,
+ userp, tidPathp, &req, &dscp);
if (code == 0) {
if (dscp->fileType == CM_SCACHETYPE_MOUNTPOINT
&& !dscp->mountRootFidp)
}
}
}
- cm_FreeSpace(spacep);
- }
+ cm_FreeSpace(spacep);
+ }
- /* now do namei and stat, and copy out the info */
+ /* now do namei and stat, and copy out the info */
code = cm_NameI(cm_rootSCachep, (char *)(&p->parmsp[3]),
- CM_FLAG_FOLLOW | CM_FLAG_CASEFOLD, userp, tidPathp, &req, &scp);
+ CM_FLAG_FOLLOW | CM_FLAG_CASEFOLD, userp, tidPathp, &req, &scp);
- if (code) {
- cm_ReleaseUser(userp);
+ if (code) {
+ cm_ReleaseUser(userp);
smb_SendTran2Error(vcp, p, opx, code);
smb_FreeTran2Packet(outp);
return 0;
}
lock_ObtainMutex(&scp->mx);
- code = cm_SyncOp(scp, NULL, userp, &req, 0,
- CM_SCACHESYNC_NEEDCALLBACK | CM_SCACHESYNC_GETSTATUS);
- if (code) goto done;
+ code = cm_SyncOp(scp, NULL, userp, &req, 0,
+ CM_SCACHESYNC_NEEDCALLBACK | CM_SCACHESYNC_GETSTATUS);
+ if (code) goto done;
/* now we have the status in the cache entry, and everything is locked.
- * Marshall the output data.
+ * Marshall the output data.
*/
- op = outp->datap;
- /* for info level 108, figure out short name */
- if (infoLevel == 0x108) {
- code = cm_GetShortName((char *)(&p->parmsp[3]), userp, &req,
+ op = outp->datap;
+ /* for info level 108, figure out short name */
+ if (infoLevel == 0x108) {
+ code = cm_GetShortName((char *)(&p->parmsp[3]), userp, &req,
tidPathp, scp->fid.vnode, shortName,
(size_t *) &len);
- if (code) {
- goto done;
- }
+ if (code) {
+ goto done;
+ }
- op = outp->datap;
- *((u_long *)op) = len * 2; op += 4;
- mbstowcs((unsigned short *)op, shortName, len);
- op += (len * 2);
+ op = outp->datap;
+ *((u_long *)op) = len * 2; op += 4;
+ mbstowcs((unsigned short *)op, shortName, len);
+ op += (len * 2);
- goto done;
- }
- if (infoLevel == 1 || infoLevel == 2) {
- smb_SearchTimeFromUnixTime(&dosTime, scp->clientModTime);
+ goto done;
+ }
+ if (infoLevel == 1 || infoLevel == 2) {
+ smb_SearchTimeFromUnixTime(&dosTime, scp->clientModTime);
*((u_long *)op) = dosTime; op += 4; /* creation time */
*((u_long *)op) = dosTime; op += 4; /* access time */
*((u_long *)op) = dosTime; op += 4; /* write time */
*((u_long *)op) = scp->length.LowPart; op += 4; /* length */
*((u_long *)op) = scp->length.LowPart; op += 4; /* alloc size */
- attributes = smb_Attributes(scp);
- *((u_short *)op) = attributes; op += 2; /* attributes */
- }
- else if (infoLevel == 0x101) {
- smb_LargeSearchTimeFromUnixTime(&ft, scp->clientModTime);
- *((FILETIME *)op) = ft; op += 8; /* creation time */
- *((FILETIME *)op) = ft; op += 8; /* last access time */
- *((FILETIME *)op) = ft; op += 8; /* last write time */
- *((FILETIME *)op) = ft; op += 8; /* last change time */
- extAttributes = smb_ExtAttributes(scp);
- *((u_long *)op) = extAttributes; op += 4; /* extended attribs */
- *((u_long *)op) = 0; op += 4; /* don't know what this is */
- }
- else if (infoLevel == 0x102) {
- *((LARGE_INTEGER *)op) = scp->length; op += 8; /* alloc size */
- *((LARGE_INTEGER *)op) = scp->length; op += 8; /* EOF */
- *((u_long *)op) = scp->linkCount; op += 4;
- *op++ = 0;
- *op++ = 0;
- *op++ = (scp->fileType == CM_SCACHETYPE_DIRECTORY ? 1 : 0);
- *op++ = 0;
- }
- else if (infoLevel == 0x103) {
- memset(op, 0, 4); op += 4; /* EA size */
- }
+ attributes = smb_Attributes(scp);
+ *((u_short *)op) = attributes; op += 2; /* attributes */
+ }
+ else if (infoLevel == 0x101) {
+ smb_LargeSearchTimeFromUnixTime(&ft, scp->clientModTime);
+ *((FILETIME *)op) = ft; op += 8; /* creation time */
+ *((FILETIME *)op) = ft; op += 8; /* last access time */
+ *((FILETIME *)op) = ft; op += 8; /* last write time */
+ *((FILETIME *)op) = ft; op += 8; /* last change time */
+ extAttributes = smb_ExtAttributes(scp);
+ *((u_long *)op) = extAttributes; op += 4; /* extended attribs */
+ *((u_long *)op) = 0; op += 4; /* don't know what this is */
+ }
+ else if (infoLevel == 0x102) {
+ *((LARGE_INTEGER *)op) = scp->length; op += 8; /* alloc size */
+ *((LARGE_INTEGER *)op) = scp->length; op += 8; /* EOF */
+ *((u_long *)op) = scp->linkCount; op += 4;
+ *op++ = 0;
+ *op++ = 0;
+ *op++ = (scp->fileType == CM_SCACHETYPE_DIRECTORY ? 1 : 0);
+ *op++ = 0;
+ }
+ else if (infoLevel == 0x103) {
+ memset(op, 0, 4); op += 4; /* EA size */
+ }
+
+ /* now, if we are being asked about extended attrs, return a 0 size */
+ if (infoLevel == 2) {
+ *((u_long *)op) = 0; op += 4;
+ }
- /* now, if we are being asked about extended attrs, return a 0 size */
- if (infoLevel == 2) {
- *((u_long *)op) = 0; op += 4;
- }
-
- /* send and free the packets */
+ /* send and free the packets */
done:
- lock_ReleaseMutex(&scp->mx);
+ lock_ReleaseMutex(&scp->mx);
cm_ReleaseSCache(scp);
cm_ReleaseUser(userp);
- if (code == 0)
+ if (code == 0)
smb_SendTran2Packet(vcp, outp, opx);
else
smb_SendTran2Error(vcp, p, opx, code);
long smb_ReceiveTran2SetPathInfo(smb_vc_t *vcp, smb_tran2Packet_t *p, smb_packet_t *outp)
{
+ osi_Log0(smb_logp,"ReceiveTran2SetPathInfo - NOT_SUPPORTED");
return CM_ERROR_BADOP;
}
long smb_ReceiveTran2QFileInfo(smb_vc_t *vcp, smb_tran2Packet_t *p, smb_packet_t *opx)
{
- smb_tran2Packet_t *outp;
- FILETIME ft;
- unsigned long attributes;
- unsigned short infoLevel;
- int nbytesRequired;
- unsigned short fid;
- cm_user_t *userp;
+ smb_tran2Packet_t *outp;
+ FILETIME ft;
+ unsigned long attributes;
+ unsigned short infoLevel;
+ int nbytesRequired;
+ unsigned short fid;
+ cm_user_t *userp;
smb_fid_t *fidp;
- cm_scache_t *scp;
- char *op;
- long code = 0;
- cm_req_t req;
+ cm_scache_t *scp;
+ char *op;
+ long code = 0;
+ cm_req_t req;
- cm_InitReq(&req);
+ cm_InitReq(&req);
fid = p->parmsp[0];
fidp = smb_FindFID(vcp, fid, 0);
- if (fidp == NULL) {
- smb_SendTran2Error(vcp, p, opx, CM_ERROR_BADFD);
- return 0;
- }
+ if (fidp == NULL) {
+ smb_SendTran2Error(vcp, p, opx, CM_ERROR_BADFD);
+ return 0;
+ }
- infoLevel = p->parmsp[1];
- if (infoLevel == 0x101) nbytesRequired = 40;
- else if (infoLevel == 0x102) nbytesRequired = 24;
- else if (infoLevel == 0x103) nbytesRequired = 4;
- else if (infoLevel == 0x104) nbytesRequired = 6;
- else {
- osi_Log2(smb_logp, "Bad Tran2 op 0x%x infolevel 0x%x",
- p->opcode, infoLevel);
- smb_SendTran2Error(vcp, p, opx, CM_ERROR_INVAL);
+ infoLevel = p->parmsp[1];
+ if (infoLevel == 0x101) nbytesRequired = 40;
+ else if (infoLevel == 0x102) nbytesRequired = 24;
+ else if (infoLevel == 0x103) nbytesRequired = 4;
+ else if (infoLevel == 0x104) nbytesRequired = 6;
+ else {
+ osi_Log2(smb_logp, "Bad Tran2 op 0x%x infolevel 0x%x",
+ p->opcode, infoLevel);
+ smb_SendTran2Error(vcp, p, opx, CM_ERROR_INVAL);
smb_ReleaseFID(fidp);
- return 0;
- }
- osi_Log2(smb_logp, "T2 QFileInfo type 0x%x fid %d", infoLevel, fid);
+ return 0;
+ }
+ osi_Log2(smb_logp, "T2 QFileInfo type 0x%x fid %d", infoLevel, fid);
- outp = smb_GetTran2ResponsePacket(vcp, p, opx, 2, nbytesRequired);
+ outp = smb_GetTran2ResponsePacket(vcp, p, opx, 2, nbytesRequired);
- if (infoLevel > 0x100)
- outp->totalParms = 2;
- else
- outp->totalParms = 0;
- outp->totalData = nbytesRequired;
+ if (infoLevel > 0x100)
+ outp->totalParms = 2;
+ else
+ outp->totalParms = 0;
+ outp->totalData = nbytesRequired;
- userp = smb_GetTran2User(vcp, p);
+ userp = smb_GetTran2User(vcp, p);
if (!userp) {
osi_Log1(smb_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);
- if (code) goto done;
+ scp = fidp->scp;
+ lock_ObtainMutex(&scp->mx);
+ code = cm_SyncOp(scp, NULL, userp, &req, 0,
+ CM_SCACHESYNC_NEEDCALLBACK | CM_SCACHESYNC_GETSTATUS);
+ if (code)
+ goto done;
- /* now we have the status in the cache entry, and everything is locked.
- * Marshall the output data.
- */
- op = outp->datap;
- if (infoLevel == 0x101) {
- smb_LargeSearchTimeFromUnixTime(&ft, scp->clientModTime);
- *((FILETIME *)op) = ft; op += 8; /* creation time */
- *((FILETIME *)op) = ft; op += 8; /* last access time */
- *((FILETIME *)op) = ft; op += 8; /* last write time */
- *((FILETIME *)op) = ft; op += 8; /* last change time */
- attributes = smb_ExtAttributes(scp);
- *((u_long *)op) = attributes; op += 4;
- *((u_long *)op) = 0; op += 4;
- }
- else if (infoLevel == 0x102) {
- *((LARGE_INTEGER *)op) = scp->length; op += 8; /* alloc size */
- *((LARGE_INTEGER *)op) = scp->length; op += 8; /* EOF */
- *((u_long *)op) = scp->linkCount; op += 4;
- *op++ = ((fidp->flags & SMB_FID_DELONCLOSE) ? 1 : 0);
- *op++ = (scp->fileType == CM_SCACHETYPE_DIRECTORY ? 1 : 0);
- *op++ = 0;
- *op++ = 0;
- }
- else if (infoLevel == 0x103) {
- *((u_long *)op) = 0; op += 4;
- }
- else if (infoLevel == 0x104) {
- unsigned long len;
- char *name;
+ /* now we have the status in the cache entry, and everything is locked.
+ * Marshall the output data.
+ */
+ op = outp->datap;
+ if (infoLevel == 0x101) {
+ smb_LargeSearchTimeFromUnixTime(&ft, scp->clientModTime);
+ *((FILETIME *)op) = ft; op += 8; /* creation time */
+ *((FILETIME *)op) = ft; op += 8; /* last access time */
+ *((FILETIME *)op) = ft; op += 8; /* last write time */
+ *((FILETIME *)op) = ft; op += 8; /* last change time */
+ attributes = smb_ExtAttributes(scp);
+ *((u_long *)op) = attributes; op += 4;
+ *((u_long *)op) = 0; op += 4;
+ }
+ else if (infoLevel == 0x102) {
+ *((LARGE_INTEGER *)op) = scp->length; op += 8; /* alloc size */
+ *((LARGE_INTEGER *)op) = scp->length; op += 8; /* EOF */
+ *((u_long *)op) = scp->linkCount; op += 4;
+ *op++ = ((fidp->flags & SMB_FID_DELONCLOSE) ? 1 : 0);
+ *op++ = (scp->fileType == CM_SCACHETYPE_DIRECTORY ? 1 : 0);
+ *op++ = 0;
+ *op++ = 0;
+ }
+ else if (infoLevel == 0x103) {
+ *((u_long *)op) = 0; op += 4;
+ }
+ else if (infoLevel == 0x104) {
+ unsigned long len;
+ char *name;
- if (fidp->NTopen_wholepathp)
- name = fidp->NTopen_wholepathp;
- else
- name = "\\"; /* probably can't happen */
- len = strlen(name);
- outp->totalData = (len*2) + 4; /* this is actually what we want to return */
- *((u_long *)op) = len * 2; op += 4;
- mbstowcs((unsigned short *)op, name, len); op += (len * 2);
- }
+ if (fidp->NTopen_wholepathp)
+ name = fidp->NTopen_wholepathp;
+ else
+ name = "\\"; /* probably can't happen */
+ len = strlen(name);
+ outp->totalData = (len*2) + 4; /* this is actually what we want to return */
+ *((u_long *)op) = len * 2; op += 4;
+ mbstowcs((unsigned short *)op, name, len); op += (len * 2);
+ }
- /* send and free the packets */
+ /* send and free the packets */
done:
- lock_ReleaseMutex(&scp->mx);
- cm_ReleaseUser(userp);
- smb_ReleaseFID(fidp);
- if (code == 0) smb_SendTran2Packet(vcp, outp, opx);
- else smb_SendTran2Error(vcp, p, opx, code);
- smb_FreeTran2Packet(outp);
+ lock_ReleaseMutex(&scp->mx);
+ cm_ReleaseUser(userp);
+ smb_ReleaseFID(fidp);
+ if (code == 0)
+ smb_SendTran2Packet(vcp, outp, opx);
+ else
+ smb_SendTran2Error(vcp, p, opx, code);
+ smb_FreeTran2Packet(outp);
- return 0;
-}
+ return 0;
+}
long smb_ReceiveTran2SetFileInfo(smb_vc_t *vcp, smb_tran2Packet_t *p, smb_packet_t *op)
{
- long code = 0;
- unsigned short fid;
- smb_fid_t *fidp;
- unsigned short infoLevel;
- smb_tran2Packet_t *outp;
- cm_user_t *userp;
- cm_scache_t *scp;
- cm_req_t req;
+ long code = 0;
+ unsigned short fid;
+ smb_fid_t *fidp;
+ unsigned short infoLevel;
+ smb_tran2Packet_t *outp;
+ cm_user_t *userp;
+ cm_scache_t *scp;
+ cm_req_t req;
- cm_InitReq(&req);
+ cm_InitReq(&req);
fid = p->parmsp[0];
- fidp = smb_FindFID(vcp, fid, 0);
+ fidp = smb_FindFID(vcp, fid, 0);
- if (fidp == NULL) {
- smb_SendTran2Error(vcp, p, op, CM_ERROR_BADFD);
- return 0;
- }
+ if (fidp == NULL) {
+ smb_SendTran2Error(vcp, p, op, CM_ERROR_BADFD);
+ return 0;
+ }
- infoLevel = p->parmsp[1];
- if (infoLevel > 0x104 || infoLevel < 0x101) {
- osi_Log2(smb_logp, "Bad Tran2 op 0x%x infolevel 0x%x",
- p->opcode, infoLevel);
- smb_SendTran2Error(vcp, p, op, CM_ERROR_INVAL);
+ infoLevel = p->parmsp[1];
+ osi_Log2(smb_logp,"ReceiveTran2SetFileInfo type=[%x] fid=[%x]", infoLevel, fid);
+ if (infoLevel > 0x104 || infoLevel < 0x101) {
+ osi_Log2(smb_logp, "Bad Tran2 op 0x%x infolevel 0x%x",
+ p->opcode, infoLevel);
+ smb_SendTran2Error(vcp, p, op, CM_ERROR_INVAL);
smb_ReleaseFID(fidp);
- return 0;
- }
+ return 0;
+ }
- if (infoLevel == 0x102 && !(fidp->flags & SMB_FID_OPENDELETE)) {
- smb_SendTran2Error(vcp, p, op, CM_ERROR_NOACCESS);
+ if (infoLevel == 0x102 && !(fidp->flags & SMB_FID_OPENDELETE)) {
+ smb_SendTran2Error(vcp, p, op, CM_ERROR_NOACCESS);
smb_ReleaseFID(fidp);
- return 0;
- }
- if ((infoLevel == 0x103 || infoLevel == 0x104)
- && !(fidp->flags & SMB_FID_OPENWRITE)) {
- smb_SendTran2Error(vcp, p, op, CM_ERROR_NOACCESS);
+ return 0;
+ }
+ if ((infoLevel == 0x103 || infoLevel == 0x104)
+ && !(fidp->flags & SMB_FID_OPENWRITE)) {
+ smb_SendTran2Error(vcp, p, op, CM_ERROR_NOACCESS);
smb_ReleaseFID(fidp);
- return 0;
- }
+ return 0;
+ }
- osi_Log1(smb_logp, "T2 SFileInfo type 0x%x", infoLevel);
+ osi_Log1(smb_logp, "T2 SFileInfo type 0x%x", infoLevel);
- outp = smb_GetTran2ResponsePacket(vcp, p, op, 2, 0);
+ outp = smb_GetTran2ResponsePacket(vcp, p, op, 2, 0);
- outp->totalParms = 2;
- outp->totalData = 0;
+ outp->totalParms = 2;
+ outp->totalData = 0;
- userp = smb_GetTran2User(vcp, p);
+ userp = smb_GetTran2User(vcp, p);
if (!userp) {
osi_Log1(smb_logp,"ReceiveTran2SetFileInfo unable to resolve user [%d]", p->uid);
code = CM_ERROR_BADSMB;
goto done;
- }
+ }
- scp = fidp->scp;
+ scp = fidp->scp;
+
+ if (infoLevel == 0x101) {
+ FILETIME lastMod;
+ unsigned int attribute;
+ cm_attr_t attr;
- if (infoLevel == 0x101) {
- FILETIME lastMod;
- unsigned int attribute;
- cm_attr_t attr;
-
- /* lock the vnode with a callback; we need the current status
- * to determine what the new status is, in some cases.
- */
- lock_ObtainMutex(&scp->mx);
- code = cm_SyncOp(scp, NULL, userp, &req, 0,
- CM_SCACHESYNC_GETSTATUS
+ /* lock the vnode with a callback; we need the current status
+ * to determine what the new status is, in some cases.
+ */
+ lock_ObtainMutex(&scp->mx);
+ code = cm_SyncOp(scp, NULL, userp, &req, 0,
+ CM_SCACHESYNC_GETSTATUS
| CM_SCACHESYNC_NEEDCALLBACK);
- if (code) {
- lock_ReleaseMutex(&scp->mx);
- goto done;
- }
+ if (code) {
+ lock_ReleaseMutex(&scp->mx);
+ goto done;
+ }
- /* prepare for setattr call */
- attr.mask = 0;
-
- lastMod = *((FILETIME *)(p->datap + 16));
- /* when called as result of move a b, lastMod is (-1, -1).
+ /* 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;
- }
+ * 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)
- && (attribute & 1) != 0) {
- /* make a writable file read-only */
- attr.mask |= CM_ATTRMASK_UNIXMODEBITS;
- attr.unixModeBits = scp->unixModeBits & ~0222;
- }
- else if ((scp->unixModeBits & 0222) == 0
- && (attribute & 1) == 0) {
- /* make a read-only file writable */
- attr.mask |= CM_ATTRMASK_UNIXMODEBITS;
- attr.unixModeBits = scp->unixModeBits | 0222;
- }
- }
- lock_ReleaseMutex(&scp->mx);
+ attribute = *((u_long *)(p->datap + 32));
+ if (attribute != 0) {
+ if ((scp->unixModeBits & 0222)
+ && (attribute & 1) != 0) {
+ /* make a writable file read-only */
+ attr.mask |= CM_ATTRMASK_UNIXMODEBITS;
+ attr.unixModeBits = scp->unixModeBits & ~0222;
+ }
+ else if ((scp->unixModeBits & 0222) == 0
+ && (attribute & 1) == 0) {
+ /* make a read-only file writable */
+ attr.mask |= CM_ATTRMASK_UNIXMODEBITS;
+ attr.unixModeBits = scp->unixModeBits | 0222;
+ }
+ }
+ lock_ReleaseMutex(&scp->mx);
+
+ /* call setattr */
+ if (attr.mask)
+ code = cm_SetAttr(scp, &attr, userp, &req);
+ else
+ code = 0;
+ }
+ else if (infoLevel == 0x103 || infoLevel == 0x104) {
+ LARGE_INTEGER size = *((LARGE_INTEGER *)(p->datap));
+ cm_attr_t attr;
+
+ attr.mask = CM_ATTRMASK_LENGTH;
+ attr.length.LowPart = size.LowPart;
+ attr.length.HighPart = size.HighPart;
+ code = cm_SetAttr(scp, &attr, userp, &req);
+ }
+ else if (infoLevel == 0x102) {
+ if (*((char *)(p->datap))) {
+ code = cm_CheckNTDelete(fidp->NTopen_dscp, scp, userp,
+ &req);
+ if (code == 0)
+ fidp->flags |= SMB_FID_DELONCLOSE;
+ }
+ else {
+ code = 0;
+ fidp->flags &= ~SMB_FID_DELONCLOSE;
+ }
+ }
- /* call setattr */
- if (attr.mask)
- code = cm_SetAttr(scp, &attr, userp, &req);
- else
- code = 0;
- }
- else if (infoLevel == 0x103 || infoLevel == 0x104) {
- LARGE_INTEGER size = *((LARGE_INTEGER *)(p->datap));
- cm_attr_t attr;
-
- attr.mask = CM_ATTRMASK_LENGTH;
- attr.length.LowPart = size.LowPart;
- attr.length.HighPart = size.HighPart;
- code = cm_SetAttr(scp, &attr, userp, &req);
- }
- else if (infoLevel == 0x102) {
- if (*((char *)(p->datap))) {
- code = cm_CheckNTDelete(fidp->NTopen_dscp, scp, userp,
- &req);
- if (code == 0)
- fidp->flags |= SMB_FID_DELONCLOSE;
- }
- else {
- code = 0;
- fidp->flags &= ~SMB_FID_DELONCLOSE;
- }
- }
done:
- cm_ReleaseUser(userp);
- smb_ReleaseFID(fidp);
- if (code == 0) smb_SendTran2Packet(vcp, outp, op);
- else smb_SendTran2Error(vcp, p, op, code);
- smb_FreeTran2Packet(outp);
+ cm_ReleaseUser(userp);
+ smb_ReleaseFID(fidp);
+ if (code == 0)
+ smb_SendTran2Packet(vcp, outp, op);
+ else
+ smb_SendTran2Error(vcp, p, op, code);
+ smb_FreeTran2Packet(outp);
- return 0;
+ return 0;
+}
+
+long
+smb_ReceiveTran2FSCTL(smb_vc_t *vcp, smb_tran2Packet_t *p, smb_packet_t *outp)
+{
+ osi_Log0(smb_logp,"ReceiveTran2FSCTL - NOT_SUPPORTED");
+ return CM_ERROR_BADOP;
+}
+
+long
+smb_ReceiveTran2IOCTL(smb_vc_t *vcp, smb_tran2Packet_t *p, smb_packet_t *outp)
+{
+ osi_Log0(smb_logp,"ReceiveTran2IOCTL - NOT_SUPPORTED");
+ return CM_ERROR_BADOP;
+}
+
+long
+smb_ReceiveTran2FindNotifyFirst(smb_vc_t *vcp, smb_tran2Packet_t *p, smb_packet_t *outp)
+{
+ osi_Log0(smb_logp,"ReceiveTran2FindNotifyFirst - NOT_SUPPORTED");
+ return CM_ERROR_BADOP;
}
-long smb_ReceiveTran2FSCTL(smb_vc_t *vcp, smb_tran2Packet_t *p, smb_packet_t *outp)
+long
+smb_ReceiveTran2FindNotifyNext(smb_vc_t *vcp, smb_tran2Packet_t *p, smb_packet_t *outp)
{
+ osi_Log0(smb_logp,"ReceiveTran2FindNotifyNext - NOT_SUPPORTED");
return CM_ERROR_BADOP;
}
-long smb_ReceiveTran2IOCTL(smb_vc_t *vcp, smb_tran2Packet_t *p, smb_packet_t *outp)
+long
+smb_ReceiveTran2CreateDirectory(smb_vc_t *vcp, smb_tran2Packet_t *p, smb_packet_t *outp)
{
+ osi_Log0(smb_logp,"ReceiveTran2CreateDirectory - NOT_SUPPORTED");
return CM_ERROR_BADOP;
}
-long smb_ReceiveTran2FindNotifyFirst(smb_vc_t *vcp, smb_tran2Packet_t *p, smb_packet_t *outp)
+long
+smb_ReceiveTran2SessionSetup(smb_vc_t *vcp, smb_tran2Packet_t *p, smb_packet_t *outp)
{
+ osi_Log0(smb_logp,"ReceiveTran2SessionSetup - NOT_SUPPORTED");
return CM_ERROR_BADOP;
}
-long smb_ReceiveTran2FindNotifyNext(smb_vc_t *vcp, smb_tran2Packet_t *p, smb_packet_t *outp)
+long
+smb_ReceiveTran2GetDFSReferral(smb_vc_t *vcp, smb_tran2Packet_t *p, smb_packet_t *outp)
{
+ osi_Log0(smb_logp,"ReceiveTran2GetDFSReferral - NOT_SUPPORTED");
return CM_ERROR_BADOP;
}
-long smb_ReceiveTran2MKDir(smb_vc_t *vcp, smb_tran2Packet_t *p, smb_packet_t *outp)
+long
+smb_ReceiveTran2ReportDFSInconsistency(smb_vc_t *vcp, smb_tran2Packet_t *p, smb_packet_t *outp)
{
+ osi_Log0(smb_logp,"ReceiveTran2ReportDFSInconsistency - NOT_SUPPORTED");
return CM_ERROR_BADOP;
}
-long smb_ApplyV3DirListPatches(cm_scache_t *dscp,
+long
+smb_ApplyV3DirListPatches(cm_scache_t *dscp,
smb_dirListPatch_t **dirPatchespp, int infoLevel, cm_user_t *userp,
cm_req_t *reqp)
{
- long code = 0;
+ long code = 0;
cm_scache_t *scp;
cm_scache_t *targetScp; /* target if scp is a symlink */
char *dptr;
time_t dosTime;
- FILETIME ft;
+ FILETIME ft;
int shortTemp;
unsigned short attr;
- unsigned long lattr;
+ unsigned long lattr;
smb_dirListPatch_t *patchp;
smb_dirListPatch_t *npatchp;
}
/* now watch for a symlink */
- if (scp->fileType == CM_SCACHETYPE_SYMLINK) {
- lock_ReleaseMutex(&scp->mx);
+ code = 0;
+ while (code == 0 && scp->fileType == CM_SCACHETYPE_SYMLINK) {
+ lock_ReleaseMutex(&scp->mx);
code = cm_EvaluateSymLink(dscp, scp, &targetScp, userp, reqp);
if (code == 0) {
- /* we have a more accurate file to use (the
- * target of the symbolic link). Otherwise,
- * we'll just use the symlink anyway.
+ /* we have a more accurate file to use (the
+ * target of the symbolic link). Otherwise,
+ * we'll just use the symlink anyway.
*/
- osi_Log2(smb_logp, "symlink vp %x to vp %x",
- scp, targetScp);
- cm_ReleaseSCache(scp);
+ osi_Log2(smb_logp, "symlink vp %x to vp %x",
+ scp, targetScp);
+ cm_ReleaseSCache(scp);
scp = targetScp;
}
lock_ObtainMutex(&scp->mx);
/* make sure we're about to open a file */
if (scp->fileType != CM_SCACHETYPE_FILE) {
- cm_ReleaseSCache(scp);
- cm_ReleaseUser(userp);
- return CM_ERROR_ISDIR;
+ cm_ReleaseSCache(scp);
+ cm_ReleaseUser(userp);
+ return CM_ERROR_ISDIR;
}
/* now all we have to do is open the file itself */
/*
* Values for createDisp, copied from NTDDK.H
- *
- * FILE_SUPERSEDE 0 (???)
- * FILE_OPEN 1 (open)
- * FILE_CREATE 2 (exclusive)
- * FILE_OPEN_IF 3 (non-exclusive)
- * FILE_OVERWRITE 4 (open & truncate, but do not create)
- * FILE_OVERWRITE_IF 5 (open & truncate, or create)
*/
+#define FILE_SUPERSEDE 0 // (???)
+#define FILE_OPEN 1 // (open)
+#define FILE_CREATE 2 // (exclusive)
+#define FILE_OPEN_IF 3 // (non-exclusive)
+#define FILE_OVERWRITE 4 // (open & truncate, but do not create)
+#define FILE_OVERWRITE_IF 5 // (open & truncate, or create)
long smb_ReceiveNTCreateX(smb_vc_t *vcp, smb_packet_t *inp, smb_packet_t *outp)
{
- char *pathp, *realPathp;
- long code = 0;
- cm_space_t *spacep;
- cm_user_t *userp;
- cm_scache_t *dscp; /* parent dir */
- cm_scache_t *scp; /* file to create or open */
- cm_attr_t setAttr;
- char *lastNamep;
+ char *pathp, *realPathp;
+ long code = 0;
+ cm_space_t *spacep;
+ cm_user_t *userp;
+ cm_scache_t *dscp; /* parent dir */
+ cm_scache_t *scp; /* file to create or open */
+ cm_scache_t *targetScp; /* if scp is a symlink */
+ cm_attr_t setAttr;
+ char *lastNamep;
char *treeStartp;
- unsigned short nameLength;
- unsigned int flags;
- unsigned int requestOpLock;
- unsigned int requestBatchOpLock;
- unsigned int mustBeDir;
+ unsigned short nameLength;
+ unsigned int flags;
+ unsigned int requestOpLock;
+ unsigned int requestBatchOpLock;
+ unsigned int mustBeDir;
unsigned int treeCreate;
- int realDirFlag;
- unsigned int desiredAccess;
- unsigned int extAttributes;
- unsigned int createDisp;
- unsigned int createOptions;
- int initialModeBits;
- unsigned short baseFid;
- smb_fid_t *baseFidp;
- smb_fid_t *fidp;
- cm_scache_t *baseDirp;
- unsigned short openAction;
- int parmSlot;
- long fidflags;
- FILETIME ft;
- LARGE_INTEGER sz;
- char *tidPathp;
- BOOL foundscp;
- cm_req_t req;
+ int realDirFlag;
+ unsigned int desiredAccess;
+ unsigned int extAttributes;
+ unsigned int createDisp;
+ unsigned int createOptions;
+ int initialModeBits;
+ unsigned short baseFid;
+ smb_fid_t *baseFidp;
+ smb_fid_t *fidp;
+ cm_scache_t *baseDirp;
+ unsigned short openAction;
+ int parmSlot;
+ long fidflags;
+ FILETIME ft;
+ LARGE_INTEGER sz;
+ char *tidPathp;
+ BOOL foundscp;
+ cm_req_t req;
- cm_InitReq(&req);
+ cm_InitReq(&req);
treeCreate = FALSE;
- foundscp = FALSE;
- scp = NULL;
+ foundscp = FALSE;
+ scp = NULL;
- nameLength = smb_GetSMBOffsetParm(inp, 2, 1);
- flags = smb_GetSMBOffsetParm(inp, 3, 1)
- | (smb_GetSMBOffsetParm(inp, 4, 1) << 16);
- requestOpLock = flags & 0x02;
- requestBatchOpLock = flags & 0x04;
- mustBeDir = flags & 0x08;
+ nameLength = smb_GetSMBOffsetParm(inp, 2, 1);
+ flags = smb_GetSMBOffsetParm(inp, 3, 1)
+ | (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.
- */
- 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);
- extAttributes = smb_GetSMBOffsetParm(inp, 13, 1)
- | (smb_GetSMBOffsetParm(inp, 14, 1) << 16);
- createDisp = smb_GetSMBOffsetParm(inp, 17, 1)
- | (smb_GetSMBOffsetParm(inp, 18, 1) << 16);
- createOptions = smb_GetSMBOffsetParm(inp, 19, 1)
- | (smb_GetSMBOffsetParm(inp, 20, 1) << 16);
-
- /* mustBeDir is never set; createOptions directory bit seems to be
+ /*
+ * 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);
+ extAttributes = smb_GetSMBOffsetParm(inp, 13, 1)
+ | (smb_GetSMBOffsetParm(inp, 14, 1) << 16);
+ createDisp = smb_GetSMBOffsetParm(inp, 17, 1)
+ | (smb_GetSMBOffsetParm(inp, 18, 1) << 16);
+ createOptions = smb_GetSMBOffsetParm(inp, 19, 1)
+ | (smb_GetSMBOffsetParm(inp, 20, 1) << 16);
+
+ /* mustBeDir is never set; createOptions directory bit seems to be
* more important
- */
- if (createOptions & 1)
- realDirFlag = 1;
- else if (createOptions & 0x40)
- realDirFlag = 0;
- else
- realDirFlag = -1;
+ */
+ if (createOptions & 1)
+ realDirFlag = 1;
+ else if (createOptions & 0x40)
+ realDirFlag = 0;
+ else
+ realDirFlag = -1;
- /*
- * compute initial mode bits based on read-only flag in
- * extended attributes
- */
- initialModeBits = 0666;
- if (extAttributes & 1) initialModeBits &= ~0222;
+ /*
+ * compute initial mode bits based on read-only flag in
+ * extended attributes
+ */
+ initialModeBits = 0666;
+ if (extAttributes & 1)
+ initialModeBits &= ~0222;
- pathp = smb_GetSMBData(inp, NULL);
- /* Sometimes path is not null-terminated, so we make a copy. */
- realPathp = malloc(nameLength+1);
- memcpy(realPathp, pathp, nameLength);
- realPathp[nameLength] = 0;
+ pathp = smb_GetSMBData(inp, NULL);
+ /* Sometimes path is not null-terminated, so we make a copy. */
+ realPathp = malloc(nameLength+1);
+ memcpy(realPathp, pathp, nameLength);
+ realPathp[nameLength] = 0;
- spacep = inp->spacep;
- smb_StripLastComponent(spacep->data, &lastNamep, realPathp);
+ spacep = inp->spacep;
+ smb_StripLastComponent(spacep->data, &lastNamep, realPathp);
osi_Log1(smb_logp,"NTCreateX for [%s]",osi_LogSaveString(smb_logp,realPathp));
- osi_Log4(smb_logp,"NTCreateX da=[%x] ea=[%x] cd=[%x] co=[%x]", desiredAccess, extAttributes, createDisp, createOptions);
- osi_Log1(smb_logp,"NTCreateX lastNamep=[%s]",osi_LogSaveString(smb_logp,(lastNamep?lastNamep:"null")));
+ osi_Log4(smb_logp,"... da=[%x] ea=[%x] cd=[%x] co=[%x]", desiredAccess, extAttributes, createDisp, createOptions);
+ osi_Log2(smb_logp,"... flags=[%x] lastNamep=[%s]", flags, osi_LogSaveString(smb_logp,(lastNamep?lastNamep:"null")));
- 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);
- osi_Log1(smb_logp,"NTCreateX Setting up IOCTL on fid[%d]",fidp->fid);
+ 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);
+ osi_Log1(smb_logp,"NTCreateX Setting up IOCTL on fid[%d]",fidp->fid);
- /* set inp->fid so that later read calls in same msg can find fid */
- inp->fid = fidp->fid;
+ /* set inp->fid so that later read calls in same msg can find fid */
+ inp->fid = fidp->fid;
- /* out parms */
- parmSlot = 2;
- smb_SetSMBParmByte(outp, parmSlot, 0); /* oplock */
- smb_SetSMBParm(outp, parmSlot, fidp->fid); parmSlot++;
- smb_SetSMBParmLong(outp, parmSlot, 1); parmSlot += 2; /* Action */
- /* times */
- memset(&ft, 0, sizeof(ft));
- smb_SetSMBParmDouble(outp, parmSlot, (char *)&ft); parmSlot += 4;
- smb_SetSMBParmDouble(outp, parmSlot, (char *)&ft); parmSlot += 4;
- smb_SetSMBParmDouble(outp, parmSlot, (char *)&ft); parmSlot += 4;
- smb_SetSMBParmDouble(outp, parmSlot, (char *)&ft); parmSlot += 4;
- smb_SetSMBParmLong(outp, parmSlot, 0); parmSlot += 2; /* attr */
- sz.HighPart = 0x7fff; sz.LowPart = 0;
- smb_SetSMBParmDouble(outp, parmSlot, (char *)&sz); parmSlot += 4; /* alen */
- smb_SetSMBParmDouble(outp, parmSlot, (char *)&sz); parmSlot += 4; /* len */
- smb_SetSMBParm(outp, parmSlot, 0); parmSlot++; /* filetype */
- smb_SetSMBParm(outp, parmSlot, 0); parmSlot++; /* dev state */
- smb_SetSMBParmByte(outp, parmSlot, 0); /* is a dir? */
- smb_SetSMBDataLength(outp, 0);
+ /* out parms */
+ parmSlot = 2;
+ smb_SetSMBParmByte(outp, parmSlot, 0); /* oplock */
+ smb_SetSMBParm(outp, parmSlot, fidp->fid); parmSlot++;
+ smb_SetSMBParmLong(outp, parmSlot, 1); parmSlot += 2; /* Action */
+ /* times */
+ memset(&ft, 0, sizeof(ft));
+ smb_SetSMBParmDouble(outp, parmSlot, (char *)&ft); parmSlot += 4;
+ smb_SetSMBParmDouble(outp, parmSlot, (char *)&ft); parmSlot += 4;
+ smb_SetSMBParmDouble(outp, parmSlot, (char *)&ft); parmSlot += 4;
+ smb_SetSMBParmDouble(outp, parmSlot, (char *)&ft); parmSlot += 4;
+ smb_SetSMBParmLong(outp, parmSlot, 0); parmSlot += 2; /* attr */
+ sz.HighPart = 0x7fff; sz.LowPart = 0;
+ smb_SetSMBParmDouble(outp, parmSlot, (char *)&sz); parmSlot += 4; /* alen */
+ smb_SetSMBParmDouble(outp, parmSlot, (char *)&sz); parmSlot += 4; /* len */
+ smb_SetSMBParm(outp, parmSlot, 0); parmSlot++; /* filetype */
+ smb_SetSMBParm(outp, parmSlot, 0); parmSlot++; /* dev state */
+ smb_SetSMBParmByte(outp, parmSlot, 0); /* is a dir? */
+ smb_SetSMBDataLength(outp, 0);
- /* clean up fid reference */
- smb_ReleaseFID(fidp);
- free(realPathp);
- return 0;
- }
+ /* clean up fid reference */
+ smb_ReleaseFID(fidp);
+ free(realPathp);
+ return 0;
+ }
#ifdef DEBUG_VERBOSE
{
return CM_ERROR_INVAL;
}
- if (baseFid == 0) {
- baseDirp = cm_rootSCachep;
- code = smb_LookupTIDPath(vcp, ((smb_t *)inp)->tid, &tidPathp);
- if(code == CM_ERROR_TIDIPC) {
+ if (baseFid == 0) {
+ baseDirp = cm_rootSCachep;
+ 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. */
+ * 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 {
+ }
+ else {
baseFidp = smb_FindFID(vcp, baseFid, 0);
if (!baseFidp) {
- osi_Log1(smb_logp, "NTCreateX Invalid base fid [%d]", baseFid);
- free(realPathp);
- cm_ReleaseUser(userp);
- return CM_ERROR_INVAL;
- }
- baseDirp = baseFidp->scp;
- tidPathp = NULL;
- }
+ osi_Log1(smb_logp, "NTCreateX Invalid base fid [%d]", baseFid);
+ free(realPathp);
+ cm_ReleaseUser(userp);
+ return CM_ERROR_INVAL;
+ }
+ baseDirp = baseFidp->scp;
+ tidPathp = NULL;
+ }
osi_Log1(smb_logp, "NTCreateX tidPathp=[%s]", (tidPathp==NULL)?"null": osi_LogSaveString(smb_logp,tidPathp));
-
+
/* 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;
+ 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;
+ dscp = NULL;
+ code = 0;
/* For an exclusive create, we want to do a case sensitive match for the last component. */
- if (createDisp == 2 || createDisp == 4 || createDisp == 5) {
+ if ( createDisp == FILE_CREATE ||
+ createDisp == FILE_OVERWRITE ||
+ createDisp == FILE_OVERWRITE_IF) {
code = cm_NameI(baseDirp, spacep->data, CM_FLAG_FOLLOW | CM_FLAG_CASEFOLD,
userp, tidPathp, &req, &dscp);
if (code == 0) {
code = cm_Lookup(dscp, (lastNamep)?(lastNamep+1):realPathp,
CM_FLAG_FOLLOW | CM_FLAG_CASEFOLD, userp, &req, &scp);
if (code == 0 && realDirFlag == 1) {
- cm_ReleaseSCache(scp);
+ cm_ReleaseSCache(scp);
cm_ReleaseSCache(dscp);
cm_ReleaseUser(userp);
free(realPathp);
userp, tidPathp, &req, &scp);
}
if (code == 0)
- foundscp = TRUE;
+ foundscp = TRUE;
- if (!foundscp || (fidflags & (SMB_FID_OPENDELETE | SMB_FID_OPENWRITE))) {
- /* look up parent directory */
+ if (!foundscp || (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.
if (code &&
(tp = strrchr(spacep->data,'\\')) &&
- (createDisp == 2) &&
+ (createDisp == FILE_CREATE) &&
(realDirFlag == 1)) {
*tp++ = 0;
treeCreate = TRUE;
}
if (!foundscp && !treeCreate) {
- if (createDisp == 2 || createDisp == 4)
+ if ( createDisp == FILE_CREATE ||
+ createDisp == FILE_OVERWRITE ||
+ createDisp == FILE_OVERWRITE_IF) {
code = cm_Lookup(dscp, lastNamep,
CM_FLAG_FOLLOW, userp, &req, &scp);
- else
- 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;
- }
- }
- }
- else {
- if (baseFid != 0)
- smb_ReleaseFID(baseFidp);
- }
+ } else {
+ 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;
+ }
+ }
+ }
+ 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
* scp is NULL.
*/
if (code == 0 && !treeCreate) {
- code = cm_CheckNTOpen(scp, desiredAccess, createDisp, userp,
- &req);
- if (code) {
- if (dscp) cm_ReleaseSCache(dscp);
- cm_ReleaseSCache(scp);
- cm_ReleaseUser(userp);
- free(realPathp);
- return code;
- }
+ code = cm_CheckNTOpen(scp, desiredAccess, createDisp, userp,
+ &req);
+ if (code) {
+ if (dscp) cm_ReleaseSCache(dscp);
+ cm_ReleaseSCache(scp);
+ cm_ReleaseUser(userp);
+ free(realPathp);
+ return code;
+ }
- if (createDisp == 2) {
- /* oops, file shouldn't be there */
- if (dscp) cm_ReleaseSCache(dscp);
- cm_ReleaseSCache(scp);
- cm_ReleaseUser(userp);
- free(realPathp);
- return CM_ERROR_EXISTS;
- }
+ if (createDisp == FILE_CREATE) {
+ /* oops, file shouldn't be there */
+ if (dscp) cm_ReleaseSCache(dscp);
+ cm_ReleaseSCache(scp);
+ cm_ReleaseUser(userp);
+ free(realPathp);
+ return CM_ERROR_EXISTS;
+ }
- 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 */
- }
- else openAction = 1; /* found existing file */
- }
- else if (createDisp == 1 || createDisp == 4) {
- /* don't create if not found */
- if (dscp) cm_ReleaseSCache(dscp);
- cm_ReleaseUser(userp);
- free(realPathp);
- return CM_ERROR_NOSUCHFILE;
- }
+ if ( createDisp == FILE_OVERWRITE ||
+ createDisp == FILE_OVERWRITE_IF) {
+ setAttr.mask = CM_ATTRMASK_LENGTH;
+ setAttr.length.LowPart = 0;
+ setAttr.length.HighPart = 0;
+ /* now watch for a symlink */
+ code = 0;
+ while (code == 0 && scp->fileType == CM_SCACHETYPE_SYMLINK) {
+ targetScp = 0;
+ code = cm_EvaluateSymLink(dscp, scp, &targetScp, userp, &req);
+ if (code == 0) {
+ /* we have a more accurate file to use (the
+ * target of the symbolic link). Otherwise,
+ * we'll just use the symlink anyway.
+ */
+ osi_Log2(smb_logp, "symlink vp %x to vp %x",
+ scp, targetScp);
+ cm_ReleaseSCache(scp);
+ scp = targetScp;
+ }
+ }
+ code = cm_SetAttr(scp, &setAttr, userp, &req);
+ openAction = 3; /* truncated existing file */
+ }
+ else openAction = 1; /* found existing file */
+ }
+ else if (createDisp == FILE_OPEN || createDisp == FILE_OVERWRITE) {
+ /* don't create if not found */
+ if (dscp) cm_ReleaseSCache(dscp);
+ cm_ReleaseUser(userp);
+ free(realPathp);
+ return CM_ERROR_NOSUCHFILE;
+ }
else if (realDirFlag == 0 || realDirFlag == -1) {
- osi_assert(dscp != NULL);
- osi_Log1(smb_logp, "smb_ReceiveNTCreateX creating file %s",
- osi_LogSaveString(smb_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);
- if (code == 0 && (dscp->flags & CM_SCACHEFLAG_ANYWATCH))
- smb_NotifyChange(FILE_ACTION_ADDED,
- FILE_NOTIFY_CHANGE_FILE_NAME,
- dscp, lastNamep, NULL, TRUE);
- if (code == CM_ERROR_EXISTS && createDisp != 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.
- */
- code = cm_Lookup(dscp, lastNamep, CM_FLAG_CASEFOLD,
- 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);
- }
- } /* lookup succeeded */
- }
- }
+ osi_assert(dscp != NULL);
+ osi_Log1(smb_logp, "smb_ReceiveNTCreateX creating file %s",
+ osi_LogSaveString(smb_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);
+ if (code == 0 && (dscp->flags & CM_SCACHEFLAG_ANYWATCH))
+ smb_NotifyChange(FILE_ACTION_ADDED,
+ FILE_NOTIFY_CHANGE_FILE_NAME,
+ dscp, lastNamep, NULL, TRUE);
+ if (code == CM_ERROR_EXISTS && createDisp != FILE_CREATE) {
+ /* 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 (createDisp == FILE_OVERWRITE_IF) {
+ setAttr.mask = CM_ATTRMASK_LENGTH;
+ setAttr.length.LowPart = 0;
+ setAttr.length.HighPart = 0;
+
+ /* now watch for a symlink */
+ code = 0;
+ while (code == 0 && scp->fileType == CM_SCACHETYPE_SYMLINK) {
+ targetScp = 0;
+ code = cm_EvaluateSymLink(dscp, scp, &targetScp, userp, &req);
+ if (code == 0) {
+ /* we have a more accurate file to use (the
+ * target of the symbolic link). Otherwise,
+ * we'll just use the symlink anyway.
+ */
+ osi_Log2(smb_logp, "symlink vp %x to vp %x",
+ scp, targetScp);
+ cm_ReleaseSCache(scp);
+ scp = targetScp;
+ }
+ }
+ code = cm_SetAttr(scp, &setAttr, userp, &req);
+ }
+ } /* lookup succeeded */
+ }
+ }
else {
- char *tp, *pp;
- char *cp; /* This component */
- int clen = 0; /* length of component */
- cm_scache_t *tscp;
- int isLast = 0;
+ 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(smb_logp, "smb_ReceiveNTCreateX creating directory [%s]",
- osi_LogSaveString(smb_logp, treeStartp));
- openAction = 2; /* created directory */
-
- setAttr.mask = CM_ATTRMASK_CLIENTMODTIME;
- setAttr.clientModTime = time(NULL);
+ /* create directory */
+ if ( !treeCreate )
+ treeStartp = lastNamep;
+ osi_assert(dscp != NULL);
+ osi_Log1(smb_logp, "smb_ReceiveNTCreateX creating directory [%s]",
+ osi_LogSaveString(smb_logp, treeStartp));
+ openAction = 2; /* created directory */
+
+ setAttr.mask = CM_ATTRMASK_CLIENTMODTIME;
+ setAttr.clientModTime = time(NULL);
- pp = treeStartp;
- cp = spacep->data;
- tscp = dscp;
-
- while (pp && *pp) {
- 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 {
- clen = tp - pp;
- strncpy(cp,pp,clen);
- *(cp + clen) = 0;
- tp++;
- }
- pp = tp;
-
- if (clen == 0) continue; /* the supplied path can't have consecutive slashes either , but */
-
- /* cp is the next component to be created. */
- code = cm_MakeDir(tscp, cp, 0, &setAttr, userp, &req);
- if (code == 0 && (tscp->flags & CM_SCACHEFLAG_ANYWATCH))
- smb_NotifyChange(FILE_ACTION_ADDED,
- FILE_NOTIFY_CHANGE_DIR_NAME,
- tscp, cp, NULL, TRUE);
- if (code == 0 ||
- (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.
- */
- code = cm_Lookup(tscp, cp, CM_FLAG_CASEFOLD,
- userp, &req, &scp);
- }
- if (code) break;
+ pp = treeStartp;
+ cp = spacep->data;
+ tscp = dscp;
+
+ while (pp && *pp) {
+ 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 {
+ clen = tp - pp;
+ strncpy(cp,pp,clen);
+ *(cp + clen) = 0;
+ tp++;
+ }
+ pp = tp;
+
+ if (clen == 0)
+ continue; /* the supplied path can't have consecutive slashes either , but */
+
+ /* cp is the next component to be created. */
+ code = cm_MakeDir(tscp, cp, 0, &setAttr, userp, &req);
+ if (code == 0 && (tscp->flags & CM_SCACHEFLAG_ANYWATCH))
+ smb_NotifyChange(FILE_ACTION_ADDED,
+ FILE_NOTIFY_CHANGE_DIR_NAME,
+ tscp, cp, NULL, TRUE);
+ if (code == 0 ||
+ (code == CM_ERROR_EXISTS && createDisp != FILE_CREATE)) {
+ /* Not an exclusive create, and someone else tried
+ * creating it already, then we open it anyway. We
+ * don't bother retrying after this, since if this next
+ * fails, that means that the file was deleted after we
+ * started this call.
+ */
+ code = cm_Lookup(tscp, cp, CM_FLAG_CASEFOLD,
+ userp, &req, &scp);
+ }
+ if (code) break;
- if (!isLast) { /* for anything other than dscp, release it unless it's the last one */
- cm_ReleaseSCache(tscp);
- tscp = scp; /* Newly created directory will be next parent */
- }
- }
+ if (!isLast) { /* for anything other than dscp, release it unless it's the last one */
+ cm_ReleaseSCache(tscp);
+ tscp = scp; /* Newly created directory will be next parent */
+ }
+ }
- /*
- if we get here and code == 0, then scp is the last directory created, and tscp is the
- parent of scp. dscp got released if dscp != tscp. both tscp and scp are held.
- */
- dscp = tscp;
+ /*
+ * if we get here and code == 0, then scp is the last directory created, and tscp is the
+ * parent of scp. dscp got released if dscp != tscp. both tscp and scp are held.
+ */
+ dscp = tscp;
}
- if (code) {
- /* something went wrong creating or truncating the file */
- if (scp) cm_ReleaseSCache(scp);
+ if (code) {
+ /* something went wrong creating or truncating the file */
+ if (scp) cm_ReleaseSCache(scp);
if (dscp) cm_ReleaseSCache(dscp);
- cm_ReleaseUser(userp);
- free(realPathp);
- return code;
- }
+ cm_ReleaseUser(userp);
+ free(realPathp);
+ return code;
+ }
+
+ /* make sure we have file vs. dir right (only applies for single component case) */
+ if (realDirFlag == 0 && scp->fileType != CM_SCACHETYPE_FILE) {
+ /* now watch for a symlink */
+ code = 0;
+ while (code == 0 && scp->fileType == CM_SCACHETYPE_SYMLINK) {
+ cm_scache_t * targetScp = 0;
+ code = cm_EvaluateSymLink(dscp, scp, &targetScp, userp, &req);
+ if (code == 0) {
+ /* we have a more accurate file to use (the
+ * target of the symbolic link). Otherwise,
+ * we'll just use the symlink anyway.
+ */
+ osi_Log2(smb_logp, "symlink vp %x to vp %x",
+ scp, targetScp);
+ cm_ReleaseSCache(scp);
+ scp = targetScp;
+ }
+ }
+
+ if (scp->fileType != CM_SCACHETYPE_FILE) {
+ cm_ReleaseSCache(scp);
+ cm_ReleaseUser(userp);
+ free(realPathp);
+ return CM_ERROR_ISDIR;
+ }
+ }
- /* 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);
- cm_ReleaseUser(userp);
- free(realPathp);
- return CM_ERROR_ISDIR;
- }
/* (only applies to single component case) */
- if (realDirFlag == 1 && scp->fileType == CM_SCACHETYPE_FILE) {
- cm_ReleaseSCache(scp);
+ if (realDirFlag == 1 && scp->fileType == CM_SCACHETYPE_FILE) {
+ cm_ReleaseSCache(scp);
if (dscp) cm_ReleaseSCache(dscp);
- cm_ReleaseUser(userp);
- free(realPathp);
- return CM_ERROR_NOTDIR;
- }
+ cm_ReleaseUser(userp);
+ free(realPathp);
+ return CM_ERROR_NOTDIR;
+ }
- /* open the file itself */
- fidp = smb_FindFID(vcp, 0, SMB_FLAG_CREATE);
- osi_assert(fidp);
- /* save a pointer to the vnode */
- fidp->scp = scp;
+ /* 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->flags = fidflags;
+ fidp->flags = fidflags;
- /* save parent dir and pathname for delete or change notification */
- if (fidflags & (SMB_FID_OPENDELETE | SMB_FID_OPENWRITE)) {
- fidp->flags |= SMB_FID_NTOPEN;
- fidp->NTopen_dscp = dscp;
- cm_HoldSCache(dscp);
- fidp->NTopen_pathp = strdup(lastNamep);
- }
- fidp->NTopen_wholepathp = realPathp;
+ /* save parent dir and pathname for delete or change notification */
+ if (fidflags & (SMB_FID_OPENDELETE | SMB_FID_OPENWRITE)) {
+ fidp->flags |= SMB_FID_NTOPEN;
+ fidp->NTopen_dscp = dscp;
+ cm_HoldSCache(dscp);
+ fidp->NTopen_pathp = strdup(lastNamep);
+ }
+ fidp->NTopen_wholepathp = realPathp;
- /* we don't need this any longer */
- if (dscp) cm_ReleaseSCache(dscp);
- cm_Open(scp, 0, userp);
+ /* we don't need this any longer */
+ if (dscp) cm_ReleaseSCache(dscp);
+ cm_Open(scp, 0, userp);
- /* set inp->fid so that later read calls in same msg can find fid */
- inp->fid = fidp->fid;
+ /* set inp->fid so that later read calls in same msg can find fid */
+ inp->fid = fidp->fid;
- /* out parms */
- parmSlot = 2;
- lock_ObtainMutex(&scp->mx);
- smb_SetSMBParmByte(outp, parmSlot, 0); /* oplock */
- smb_SetSMBParm(outp, parmSlot, fidp->fid); parmSlot++;
- smb_SetSMBParmLong(outp, parmSlot, openAction); parmSlot += 2;
- smb_LargeSearchTimeFromUnixTime(&ft, scp->clientModTime);
- smb_SetSMBParmDouble(outp, parmSlot, (char *)&ft); parmSlot += 4;
- smb_SetSMBParmDouble(outp, parmSlot, (char *)&ft); parmSlot += 4;
- 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;
- 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 */
- smb_SetSMBParm(outp, parmSlot, 0); parmSlot++; /* dev state */
- smb_SetSMBParmByte(outp, parmSlot,
- scp->fileType == CM_SCACHETYPE_DIRECTORY); /* is a dir? */
- lock_ReleaseMutex(&scp->mx);
- smb_SetSMBDataLength(outp, 0);
+ /* out parms */
+ parmSlot = 2;
+ lock_ObtainMutex(&scp->mx);
+ smb_SetSMBParmByte(outp, parmSlot, 0); /* oplock */
+ smb_SetSMBParm(outp, parmSlot, fidp->fid); parmSlot++;
+ smb_SetSMBParmLong(outp, parmSlot, openAction); parmSlot += 2;
+ smb_LargeSearchTimeFromUnixTime(&ft, scp->clientModTime);
+ smb_SetSMBParmDouble(outp, parmSlot, (char *)&ft); parmSlot += 4;
+ smb_SetSMBParmDouble(outp, parmSlot, (char *)&ft); parmSlot += 4;
+ 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;
+ 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 */
+ smb_SetSMBParm(outp, parmSlot, 0); parmSlot++; /* dev state */
+ smb_SetSMBParmByte(outp, parmSlot,
+ scp->fileType == CM_SCACHETYPE_DIRECTORY); /* is a dir? */
+ lock_ReleaseMutex(&scp->mx);
+ smb_SetSMBDataLength(outp, 0);
- osi_Log2(smb_logp, "SMB NT CreateX opening fid %d path %s", fidp->fid,
- osi_LogSaveString(smb_logp, realPathp));
+ osi_Log2(smb_logp, "SMB NT CreateX opening fid %d path %s", fidp->fid,
+ osi_LogSaveString(smb_logp, realPathp));
- smb_ReleaseFID(fidp);
+ smb_ReleaseFID(fidp);
- cm_ReleaseUser(userp);
+ cm_ReleaseUser(userp);
/* 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;
-}
+ /* leave scp held since we put it in fidp->scp */
+ return 0;
+}
/*
* A lot of stuff copied verbatim from NT Create&X to NT Tran Create.
*/
long smb_ReceiveNTTranCreate(smb_vc_t *vcp, smb_packet_t *inp, smb_packet_t *outp)
{
- char *pathp, *realPathp;
- long code = 0;
- cm_space_t *spacep;
- cm_user_t *userp;
- cm_scache_t *dscp; /* parent dir */
- cm_scache_t *scp; /* file to create or open */
- cm_attr_t setAttr;
- char *lastNamep;
- unsigned long nameLength;
- unsigned int flags;
- unsigned int requestOpLock;
- unsigned int requestBatchOpLock;
- unsigned int mustBeDir;
+ char *pathp, *realPathp;
+ long code = 0;
+ cm_space_t *spacep;
+ cm_user_t *userp;
+ cm_scache_t *dscp; /* parent dir */
+ cm_scache_t *scp; /* file to create or open */
+ cm_scache_t *targetScp; /* if scp is a symlink */
+ cm_attr_t setAttr;
+ char *lastNamep;
+ unsigned long nameLength;
+ unsigned int flags;
+ unsigned int requestOpLock;
+ unsigned int requestBatchOpLock;
+ unsigned int mustBeDir;
unsigned int extendedRespRequired;
- int realDirFlag;
- unsigned int desiredAccess;
+ int realDirFlag;
+ unsigned int desiredAccess;
#ifdef DEBUG_VERBOSE
unsigned int allocSize;
unsigned int shareAccess;
#endif
- unsigned int extAttributes;
- unsigned int createDisp;
+ unsigned int extAttributes;
+ unsigned int createDisp;
#ifdef DEBUG_VERBOSE
unsigned int sdLen;
#endif
- unsigned int createOptions;
- int initialModeBits;
- unsigned short baseFid;
- smb_fid_t *baseFidp;
- smb_fid_t *fidp;
- cm_scache_t *baseDirp;
- unsigned short openAction;
- int parmSlot;
- long fidflags;
- FILETIME ft;
- char *tidPathp;
- BOOL foundscp;
- int parmOffset, dataOffset;
- char *parmp;
- ULONG *lparmp;
- char *outData;
- cm_req_t req;
+ unsigned int createOptions;
+ int initialModeBits;
+ unsigned short baseFid;
+ smb_fid_t *baseFidp;
+ smb_fid_t *fidp;
+ cm_scache_t *baseDirp;
+ unsigned short openAction;
+ int parmSlot;
+ long fidflags;
+ FILETIME ft;
+ char *tidPathp;
+ BOOL foundscp;
+ int parmOffset, dataOffset;
+ char *parmp;
+ ULONG *lparmp;
+ char *outData;
+ cm_req_t req;
- cm_InitReq(&req);
+ cm_InitReq(&req);
- foundscp = FALSE;
- scp = NULL;
+ foundscp = FALSE;
+ scp = NULL;
- parmOffset = smb_GetSMBOffsetParm(inp, 11, 1)
- | (smb_GetSMBOffsetParm(inp, 12, 1) << 16);
- parmp = inp->data + parmOffset;
- lparmp = (ULONG *) parmp;
+ parmOffset = smb_GetSMBOffsetParm(inp, 11, 1)
+ | (smb_GetSMBOffsetParm(inp, 12, 1) << 16);
+ parmp = inp->data + parmOffset;
+ lparmp = (ULONG *) parmp;
- flags = lparmp[0];
- requestOpLock = flags & 0x02;
- requestBatchOpLock = flags & 0x04;
- mustBeDir = flags & 0x08;
+ flags = lparmp[0];
+ requestOpLock = flags & 0x02;
+ requestBatchOpLock = flags & 0x04;
+ mustBeDir = flags & 0x08;
extendedRespRequired = flags & 0x10;
- /*
- * Why all of a sudden 32-bit FID?
- * We will reject all bits higher than 16.
- */
- if (lparmp[1] & 0xFFFF0000)
- return CM_ERROR_INVAL;
- baseFid = (unsigned short)lparmp[1];
- desiredAccess = lparmp[2];
+ /*
+ * Why all of a sudden 32-bit FID?
+ * We will reject all bits higher than 16.
+ */
+ if (lparmp[1] & 0xFFFF0000)
+ return CM_ERROR_INVAL;
+ baseFid = (unsigned short)lparmp[1];
+ desiredAccess = lparmp[2];
#ifdef DEBUG_VERBOSE
allocSize = lparmp[3];
#endif /* DEBUG_VERSOSE */
- extAttributes = lparmp[5];
+ extAttributes = lparmp[5];
#ifdef DEBUG_VEROSE
shareAccess = lparmp[6];
#endif
- createDisp = lparmp[7];
- createOptions = lparmp[8];
+ createDisp = lparmp[7];
+ createOptions = lparmp[8];
#ifdef DEBUG_VERBOSE
sdLen = lparmp[9];
#endif
- nameLength = lparmp[11];
+ nameLength = lparmp[11];
#ifdef DEBUG_VERBOSE
- osi_Log4(smb_logp,"NTTransCreate with da[%x],ea[%x],sa[%x],cd[%x]",desiredAccess,extAttributes,shareAccess,createDisp);
- osi_Log2(smb_logp,"... co[%x],sdl[%x],as[%x]",createOptions,sdLen,allocSize);
- osi_Log1(smb_logp,"... flags[%x]",flags);
+ osi_Log4(smb_logp,"NTTranCreate with da[%x],ea[%x],sa[%x],cd[%x]",desiredAccess,extAttributes,shareAccess,createDisp);
+ osi_Log3(smb_logp,"... co[%x],sdl[%x],as[%x]",createOptions,sdLen,allocSize);
+ osi_Log1(smb_logp,"... flags[%x]",flags);
#endif
- /* mustBeDir is never set; createOptions directory bit seems to be
- * more important
- */
- if (createOptions & 1)
- realDirFlag = 1;
- else if (createOptions & 0x40)
- realDirFlag = 0;
- else
- realDirFlag = -1;
+ /* mustBeDir is never set; createOptions directory bit seems to be
+ * more important
+ */
+ if (createOptions & 1)
+ realDirFlag = 1;
+ else if (createOptions & 0x40)
+ realDirFlag = 0;
+ else
+ realDirFlag = -1;
- /*
- * compute initial mode bits based on read-only flag in
- * extended attributes
- */
- initialModeBits = 0666;
- if (extAttributes & 1) initialModeBits &= ~0222;
+ /*
+ * compute initial mode bits based on read-only flag in
+ * extended attributes
+ */
+ initialModeBits = 0666;
+ if (extAttributes & 1)
+ initialModeBits &= ~0222;
- pathp = parmp + (13 * sizeof(ULONG)) + sizeof(UCHAR);
- /* Sometimes path is not null-terminated, so we make a copy. */
- realPathp = malloc(nameLength+1);
- memcpy(realPathp, pathp, nameLength);
- realPathp[nameLength] = 0;
+ pathp = parmp + (13 * sizeof(ULONG)) + sizeof(UCHAR);
+ /* Sometimes path is not null-terminated, so we make a copy. */
+ realPathp = malloc(nameLength+1);
+ memcpy(realPathp, pathp, nameLength);
+ realPathp[nameLength] = 0;
- spacep = cm_GetSpace();
- smb_StripLastComponent(spacep->data, &lastNamep, realPathp);
+ spacep = cm_GetSpace();
+ smb_StripLastComponent(spacep->data, &lastNamep, realPathp);
- /*
- * Nothing here to handle SMB_IOCTL_FILENAME.
- * Will add it if necessary.
- */
+ /*
+ * Nothing here to handle SMB_IOCTL_FILENAME.
+ * Will add it if necessary.
+ */
#ifdef DEBUG_VERBOSE
- {
- char *hexp, *asciip;
- asciip = (lastNamep? lastNamep : realPathp);
- hexp = osi_HexifyString( asciip );
- DEBUG_EVENT2("AFS", "NTTranCreate H[%s] A[%s]", hexp, asciip);
- free(hexp);
- }
+ {
+ char *hexp, *asciip;
+ asciip = (lastNamep? lastNamep : realPathp);
+ hexp = osi_HexifyString( asciip );
+ DEBUG_EVENT2("AFS", "NTTranCreate H[%s] A[%s]", hexp, asciip);
+ free(hexp);
+ }
#endif
- userp = smb_GetUser(vcp, inp);
+ userp = smb_GetUser(vcp, inp);
if (!userp) {
osi_Log1(smb_logp, "NTTranCreate invalid user [%d]", ((smb_t *) inp)->uid);
free(realPathp);
return CM_ERROR_INVAL;
}
- if (baseFid == 0) {
- baseDirp = cm_rootSCachep;
- code = smb_LookupTIDPath(vcp, ((smb_t *)inp)->tid, &tidPathp);
+ if (baseFid == 0) {
+ baseDirp = cm_rootSCachep;
+ 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. */
+ * 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 {
+ }
+ else {
baseFidp = smb_FindFID(vcp, baseFid, 0);
if (!baseFidp) {
osi_Log1(smb_logp, "NTTranCreate Invalid fid [%d]", baseFid);
- free(realPathp);
- cm_ReleaseUser(userp);
- return CM_ERROR_INVAL;
- }
- baseDirp = baseFidp->scp;
- tidPathp = NULL;
- }
+ free(realPathp);
+ cm_ReleaseUser(userp);
+ return CM_ERROR_INVAL;
+ }
+ baseDirp = baseFidp->scp;
+ tidPathp = NULL;
+ }
/* compute open mode */
fidflags = 0;
if (desiredAccess & AFS_ACCESS_WRITE)
fidflags |= SMB_FID_OPENWRITE;
- dscp = NULL;
- code = 0;
- if (createDisp == 2 || createDisp == 4 || createDisp == 5) {
+ dscp = NULL;
+ code = 0;
+ if ( createDisp == FILE_OPEN ||
+ createDisp == FILE_OVERWRITE ||
+ createDisp == FILE_OVERWRITE_IF) {
code = cm_NameI(baseDirp, spacep->data, CM_FLAG_FOLLOW | CM_FLAG_CASEFOLD,
userp, tidPathp, &req, &dscp);
if (code == 0) {
code = cm_Lookup(dscp, (lastNamep)?(lastNamep+1):realPathp,
CM_FLAG_FOLLOW | CM_FLAG_CASEFOLD, userp, &req, &scp);
if (code == 0 && realDirFlag == 1) {
- cm_ReleaseSCache(scp);
+ cm_ReleaseSCache(scp);
cm_ReleaseSCache(dscp);
cm_ReleaseUser(userp);
free(realPathp);
userp, tidPathp, &req, &scp);
}
- if (code == 0) foundscp = TRUE;
- if (code != 0
- || (fidflags & (SMB_FID_OPENDELETE | SMB_FID_OPENWRITE))) {
- /* look up parent directory */
+ if (code == 0)
+ foundscp = TRUE;
+ if (code != 0
+ || (fidflags & (SMB_FID_OPENDELETE | SMB_FID_OPENWRITE))) {
+ /* look up parent directory */
if ( !dscp ) {
code = cm_NameI(baseDirp, spacep->data,
CM_FLAG_FOLLOW | CM_FLAG_CASEFOLD,
cm_FreeSpace(spacep);
- if (baseFid != 0) {
- smb_ReleaseFID(baseFidp);
- baseFidp = 0;
+ if (baseFid != 0) {
+ smb_ReleaseFID(baseFidp);
+ baseFidp = 0;
}
- if (code) {
- cm_ReleaseUser(userp);
- free(realPathp);
- return code;
- }
+ if (code) {
+ cm_ReleaseUser(userp);
+ free(realPathp);
+ return code;
+ }
- if (!lastNamep) lastNamep = realPathp;
- else lastNamep++;
+ if (!lastNamep) lastNamep = realPathp;
+ else lastNamep++;
if (!smb_IsLegalFilename(lastNamep))
return CM_ERROR_BADNTFILENAME;
- if (!foundscp) {
- if (createDisp == 2 || createDisp == 4)
+ if (!foundscp) {
+ if (createDisp == FILE_CREATE || createDisp == FILE_OVERWRITE_IF) {
code = cm_Lookup(dscp, lastNamep,
- CM_FLAG_FOLLOW, userp, &req, &scp);
- else
+ CM_FLAG_FOLLOW, userp, &req, &scp);
+ } else {
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;
- }
- }
- }
- else {
- if (baseFid != 0) {
+ }
+ if (code && code != CM_ERROR_NOSUCHFILE) {
+ cm_ReleaseSCache(dscp);
+ cm_ReleaseUser(userp);
+ free(realPathp);
+ return code;
+ }
+ }
+ }
+ else {
+ if (baseFid != 0) {
smb_ReleaseFID(baseFidp);
baseFidp = 0;
}
- cm_FreeSpace(spacep);
- }
+ 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. 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_CheckNTOpen(scp, desiredAccess, createDisp, userp,
- &req);
- if (code) {
- if (dscp) cm_ReleaseSCache(dscp);
- cm_ReleaseSCache(scp);
- cm_ReleaseUser(userp);
- free(realPathp);
- 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 (code == 0) {
+ code = cm_CheckNTOpen(scp, desiredAccess, createDisp, userp,
+ &req);
+ if (code) {
+ if (dscp) cm_ReleaseSCache(dscp);
+ cm_ReleaseSCache(scp);
+ cm_ReleaseUser(userp);
+ free(realPathp);
+ return code;
+ }
- if (createDisp == 2) {
- /* oops, file shouldn't be there */
- if (dscp) cm_ReleaseSCache(dscp);
- cm_ReleaseSCache(scp);
- cm_ReleaseUser(userp);
- free(realPathp);
- return CM_ERROR_EXISTS;
- }
+ if (createDisp == FILE_CREATE) {
+ /* oops, file shouldn't be there */
+ if (dscp) cm_ReleaseSCache(dscp);
+ cm_ReleaseSCache(scp);
+ cm_ReleaseUser(userp);
+ free(realPathp);
+ return CM_ERROR_EXISTS;
+ }
- 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 */
- }
- else openAction = 1; /* found existing file */
- }
- else if (createDisp == 1 || createDisp == 4) {
- /* don't create if not found */
- if (dscp) cm_ReleaseSCache(dscp);
- cm_ReleaseUser(userp);
- free(realPathp);
- return CM_ERROR_NOSUCHFILE;
- }
- else if (realDirFlag == 0 || realDirFlag == -1) {
- osi_assert(dscp != NULL);
- osi_Log1(smb_logp, "smb_ReceiveNTTranCreate creating file %s",
- osi_LogSaveString(smb_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);
- if (code == 0 && (dscp->flags & CM_SCACHEFLAG_ANYWATCH))
- smb_NotifyChange(FILE_ACTION_ADDED,
- FILE_NOTIFY_CHANGE_FILE_NAME,
- dscp, lastNamep, NULL, TRUE);
- if (code == CM_ERROR_EXISTS && createDisp != 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.
- */
- code = cm_Lookup(dscp, lastNamep, CM_FLAG_CASEFOLD,
- 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);
- }
- } /* lookup succeeded */
- }
- }
- else {
- /* create directory */
- osi_assert(dscp != NULL);
- osi_Log1(smb_logp,
- "smb_ReceiveNTTranCreate creating directory %s",
- osi_LogSaveString(smb_logp, lastNamep));
- openAction = 2; /* created directory */
- setAttr.mask = CM_ATTRMASK_CLIENTMODTIME;
- setAttr.clientModTime = time(NULL);
- code = cm_MakeDir(dscp, lastNamep, 0, &setAttr, userp, &req);
- if (code == 0 && (dscp->flags & CM_SCACHEFLAG_ANYWATCH))
- smb_NotifyChange(FILE_ACTION_ADDED,
- FILE_NOTIFY_CHANGE_DIR_NAME,
- dscp, lastNamep, NULL, TRUE);
- if (code == 0
- || (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.
- */
- code = cm_Lookup(dscp, lastNamep, CM_FLAG_CASEFOLD,
- userp, &req, &scp);
- }
- }
+ if (createDisp == FILE_OVERWRITE ||
+ createDisp == FILE_OVERWRITE_IF) {
+ setAttr.mask = CM_ATTRMASK_LENGTH;
+ setAttr.length.LowPart = 0;
+ setAttr.length.HighPart = 0;
- if (code) {
- /* something went wrong creating or truncating the file */
- if (scp) cm_ReleaseSCache(scp);
- cm_ReleaseUser(userp);
- free(realPathp);
- return code;
- }
+ /* now watch for a symlink */
+ code = 0;
+ while (code == 0 && scp->fileType == CM_SCACHETYPE_SYMLINK) {
+ targetScp = 0;
+ code = cm_EvaluateSymLink(dscp, scp, &targetScp, userp, &req);
+ if (code == 0) {
+ /* we have a more accurate file to use (the
+ * target of the symbolic link). Otherwise,
+ * we'll just use the symlink anyway.
+ */
+ osi_Log2(smb_logp, "symlink vp %x to vp %x",
+ scp, targetScp);
+ cm_ReleaseSCache(scp);
+ scp = targetScp;
+ }
+ }
+ code = cm_SetAttr(scp, &setAttr, userp, &req);
+ openAction = 3; /* truncated existing file */
+ }
+ else openAction = 1; /* found existing file */
+ }
+ else if (createDisp == FILE_OPEN || createDisp == FILE_OVERWRITE) {
+ /* don't create if not found */
+ if (dscp) cm_ReleaseSCache(dscp);
+ cm_ReleaseUser(userp);
+ free(realPathp);
+ return CM_ERROR_NOSUCHFILE;
+ }
+ else if (realDirFlag == 0 || realDirFlag == -1) {
+ osi_assert(dscp != NULL);
+ osi_Log1(smb_logp, "smb_ReceiveNTTranCreate creating file %s",
+ osi_LogSaveString(smb_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);
+ if (code == 0 && (dscp->flags & CM_SCACHEFLAG_ANYWATCH))
+ smb_NotifyChange(FILE_ACTION_ADDED,
+ FILE_NOTIFY_CHANGE_FILE_NAME,
+ dscp, lastNamep, NULL, TRUE);
+ if (code == CM_ERROR_EXISTS && createDisp != FILE_CREATE) {
+ /* 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 (createDisp == FILE_OVERWRITE_IF) {
+ setAttr.mask = CM_ATTRMASK_LENGTH;
+ setAttr.length.LowPart = 0;
+ setAttr.length.HighPart = 0;
- /* make sure we have file vs. dir right */
- if (realDirFlag == 0 && scp->fileType != CM_SCACHETYPE_FILE) {
- cm_ReleaseSCache(scp);
- cm_ReleaseUser(userp);
- free(realPathp);
- return CM_ERROR_ISDIR;
- }
- if (realDirFlag == 1 && scp->fileType == CM_SCACHETYPE_FILE) {
- cm_ReleaseSCache(scp);
- cm_ReleaseUser(userp);
- free(realPathp);
- return CM_ERROR_NOTDIR;
- }
+ /* now watch for a symlink */
+ code = 0;
+ while (code == 0 && scp->fileType == CM_SCACHETYPE_SYMLINK) {
+ targetScp = 0;
+ code = cm_EvaluateSymLink(dscp, scp, &targetScp, userp, &req);
+ if (code == 0) {
+ /* we have a more accurate file to use (the
+ * target of the symbolic link). Otherwise,
+ * we'll just use the symlink anyway.
+ */
+ osi_Log2(smb_logp, "symlink vp %x to vp %x",
+ scp, targetScp);
+ cm_ReleaseSCache(scp);
+ scp = targetScp;
+ }
+ }
+ code = cm_SetAttr(scp, &setAttr, userp, &req);
+ }
+ } /* lookup succeeded */
+ }
+ }
+ else {
+ /* create directory */
+ osi_assert(dscp != NULL);
+ osi_Log1(smb_logp,
+ "smb_ReceiveNTTranCreate creating directory %s",
+ osi_LogSaveString(smb_logp, lastNamep));
+ openAction = 2; /* created directory */
+ setAttr.mask = CM_ATTRMASK_CLIENTMODTIME;
+ setAttr.clientModTime = time(NULL);
+ code = cm_MakeDir(dscp, lastNamep, 0, &setAttr, userp, &req);
+ if (code == 0 && (dscp->flags & CM_SCACHEFLAG_ANYWATCH))
+ smb_NotifyChange(FILE_ACTION_ADDED,
+ FILE_NOTIFY_CHANGE_DIR_NAME,
+ dscp, lastNamep, NULL, TRUE);
+ if (code == 0 ||
+ (code == CM_ERROR_EXISTS && createDisp != FILE_CREATE)) {
+ /* Not an exclusive create, and someone else tried
+ * creating it already, then we open it anyway. We
+ * don't bother retrying after this, since if this next
+ * fails, that means that the file was deleted after we
+ * started this call.
+ */
+ code = cm_Lookup(dscp, lastNamep, CM_FLAG_CASEFOLD,
+ userp, &req, &scp);
+ }
+ }
- /* open the file itself */
- fidp = smb_FindFID(vcp, 0, SMB_FLAG_CREATE);
- osi_assert(fidp);
+ if (code) {
+ /* something went wrong creating or truncating the file */
+ if (scp) cm_ReleaseSCache(scp);
+ cm_ReleaseUser(userp);
+ free(realPathp);
+ return code;
+ }
- /* save a pointer to the vnode */
- fidp->scp = scp;
+ /* make sure we have file vs. dir right */
+ if (realDirFlag == 0 && scp->fileType != CM_SCACHETYPE_FILE) {
+ /* now watch for a symlink */
+ code = 0;
+ while (code == 0 && scp->fileType == CM_SCACHETYPE_SYMLINK) {
+ targetScp = 0;
+ code = cm_EvaluateSymLink(dscp, scp, &targetScp, userp, &req);
+ if (code == 0) {
+ /* we have a more accurate file to use (the
+ * target of the symbolic link). Otherwise,
+ * we'll just use the symlink anyway.
+ */
+ osi_Log2(smb_logp, "symlink vp %x to vp %x",
+ scp, targetScp);
+ cm_ReleaseSCache(scp);
+ scp = targetScp;
+ }
+ }
+
+ if (scp->fileType != CM_SCACHETYPE_FILE) {
+ cm_ReleaseSCache(scp);
+ cm_ReleaseUser(userp);
+ free(realPathp);
+ return CM_ERROR_ISDIR;
+ }
+ }
+
+ if (realDirFlag == 1 && scp->fileType == CM_SCACHETYPE_FILE) {
+ cm_ReleaseSCache(scp);
+ cm_ReleaseUser(userp);
+ free(realPathp);
+ return CM_ERROR_NOTDIR;
+ }
+
+ /* open the file itself */
+ fidp = smb_FindFID(vcp, 0, SMB_FLAG_CREATE);
+ osi_assert(fidp);
- fidp->flags = fidflags;
+ /* save a pointer to the vnode */
+ fidp->scp = scp;
+
+ fidp->flags = fidflags;
/* save parent dir and pathname for deletion or change notification */
if (fidflags & (SMB_FID_OPENDELETE | SMB_FID_OPENWRITE)) {
cm_HoldSCache(dscp);
fidp->NTopen_pathp = strdup(lastNamep);
}
- fidp->NTopen_wholepathp = realPathp;
+ fidp->NTopen_wholepathp = realPathp;
- /* we don't need this any longer */
- if (dscp) cm_ReleaseSCache(dscp);
+ /* we don't need this any longer */
+ if (dscp) cm_ReleaseSCache(dscp);
- cm_Open(scp, 0, userp);
+ cm_Open(scp, 0, userp);
- /* set inp->fid so that later read calls in same msg can find fid */
- inp->fid = fidp->fid;
+ /* 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 an extended response */
if (!extendedRespRequired) {
lock_ReleaseMutex(&scp->mx);
}
- osi_Log1(smb_logp, "SMB NTTranCreate opening fid %d", fidp->fid);
+ osi_Log1(smb_logp, "SMB NTTranCreate opening fid %d", fidp->fid);
- smb_ReleaseFID(fidp);
+ smb_ReleaseFID(fidp);
- cm_ReleaseUser(userp);
+ cm_ReleaseUser(userp);
- /* 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;
+ /* 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;
}
long smb_ReceiveNTTranNotifyChange(smb_vc_t *vcp, smb_packet_t *inp,
long smb_ReceiveNTTransact(smb_vc_t *vcp, smb_packet_t *inp, smb_packet_t *outp)
{
- unsigned short function;
+ unsigned short function;
- function = smb_GetSMBParm(inp, 18);
+ function = smb_GetSMBParm(inp, 18);
- osi_Log1(smb_logp, "SMB NT Transact function %d", function);
+ osi_Log1(smb_logp, "SMB NT Transact function %d", function);
- /* We can handle long names */
- if (vcp->flags & SMB_VCFLAG_USENT)
- ((smb_t *)outp)->flg2 |= 0x40; /* IS_LONG_NAME */
+ /* We can handle long names */
+ if (vcp->flags & SMB_VCFLAG_USENT)
+ ((smb_t *)outp)->flg2 |= 0x40; /* IS_LONG_NAME */
- switch (function) {
-
- case 6: return smb_ReceiveNTTranQuerySecurityDesc(vcp, inp, outp);
-
- case 4: return smb_ReceiveNTTranNotifyChange(vcp, inp, outp);
-
- case 1: return smb_ReceiveNTTranCreate(vcp, inp, outp);
-
- default: return CM_ERROR_INVAL;
- }
+ switch (function) {
+ case 6:
+ return smb_ReceiveNTTranQuerySecurityDesc(vcp, inp, outp);
+ case 4:
+ return smb_ReceiveNTTranNotifyChange(vcp, inp, outp);
+ case 1:
+ return smb_ReceiveNTTranCreate(vcp, inp, outp);
+ default:
+ return CM_ERROR_INVAL;
+ }
}
/*
return 0;
}
+/*
+ * NT rename also does hard links.
+ */
+
+#define RENAME_FLAG_MOVE_CLUSTER_INFORMATION 0x102
+#define RENAME_FLAG_HARD_LINK 0x103
+#define RENAME_FLAG_RENAME 0x104
+#define RENAME_FLAG_COPY 0x105
+
+long smb_ReceiveNTRename(smb_vc_t *vcp, smb_packet_t *inp, smb_packet_t *outp)
+{
+ char *oldname, *newname;
+ long code = 0;
+ cm_user_t *userp;
+ char * tp;
+ int attrs;
+ int rename_type;
+
+ attrs = smb_GetSMBParm(inp, 0);
+ rename_type = smb_GetSMBParm(inp, 1);
+
+ if (rename_type != RENAME_FLAG_RENAME && rename_type != RENAME_FLAG_HARD_LINK) {
+ osi_Log1(smb_logp, "NTRename invalid infolevel [%x]", rename_type);
+ return CM_ERROR_NOACCESS;
+ }
+
+ tp = smb_GetSMBData(inp, NULL);
+ oldname = smb_ParseASCIIBlock(tp, &tp);
+ newname = smb_ParseASCIIBlock(tp, &tp);
+
+ osi_Log3(smb_logp, "NTRename for [%s]->[%s] type [%s]",
+ osi_LogSaveString(smb_logp, oldname),
+ osi_LogSaveString(smb_logp, newname),
+ ((rename_type==RENAME_FLAG_RENAME)?"rename":"hardlink"));
+
+ if (rename_type == RENAME_FLAG_RENAME) {
+ code = smb_Rename(vcp,inp,oldname,newname,attrs);
+ } else { /* RENAME_FLAG_HARD_LINK */
+ code = smb_Link(vcp,inp,oldname,newname);
+ }
+ return code;
+}
+
void smb3_Init()
{
- lock_InitializeMutex(&smb_Dir_Watch_Lock, "Directory Watch List Lock");
+ lock_InitializeMutex(&smb_Dir_Watch_Lock, "Directory Watch List Lock");
}
cm_user_t *smb_FindCMUserByName(/*smb_vc_t *vcp,*/ char *usern, char *machine)