/*
* Copyright 2000, International Business Machines Corporation and others.
* All Rights Reserved.
- *
+ *
* This software has been released under the terms of the IBM Public
* License. For details, see the LICENSE file in the top-level source
* directory or online at http://www.openafs.org/dl/license10.html
*/
+#include <afsconfig.h>
#include <afs/param.h>
+#include <roken.h>
+
#include <afs/stds.h>
#include <windows.h>
+#include <sddl.h>
#include <stdlib.h>
#include <malloc.h>
#include <string.h>
smb_ioctlProc_t *smb_ioctlProcsp[SMB_IOCTL_MAXPROCS];
-void
+void
smb_InitIoctl(void)
{
int i;
smb_ioctlProcsp[VIOC_GETFILETYPE] = smb_IoctlGetFileType;
smb_ioctlProcsp[VIOC_VOLSTAT_TEST] = smb_IoctlVolStatTest;
smb_ioctlProcsp[VIOC_UNICODECTL] = smb_IoctlUnicodeControl;
-}
+ smb_ioctlProcsp[VIOC_SETOWNER] = smb_IoctlSetOwner;
+ smb_ioctlProcsp[VIOC_SETGROUP] = smb_IoctlSetGroup;
+ smb_ioctlProcsp[VIOCNEWCELL2] = smb_IoctlNewCell2;
+ smb_ioctlProcsp[VIOC_SETUNIXMODE] = smb_IoctlSetUnixMode;
+ smb_ioctlProcsp[VIOC_GETUNIXMODE] = smb_IoctlSetUnixMode;
+}
/* called to make a fid structure into an IOCTL fid structure */
-void
+void
smb_SetupIoctlFid(smb_fid_t *fidp, cm_space_t *prefix)
{
smb_ioctl_t *iop;
* call to the ioctl code.
*/
afs_int32
-smb_IoctlPrepareRead(struct smb_fid *fidp, smb_ioctl_t *ioctlp, cm_user_t *userp)
+smb_IoctlPrepareRead(struct smb_fid *fidp, smb_ioctl_t *ioctlp, cm_user_t *userp, afs_uint32 pflags)
{
afs_int32 opcode;
smb_ioctlProc_t *procp = NULL;
if (ioctlp->ioctl.flags & CM_IOCTLFLAG_DATAIN) {
ioctlp->ioctl.flags &= ~CM_IOCTLFLAG_DATAIN;
+ ioctlp->ioctl.flags |= CM_IOCTLFLAG_DATAOUT;
/* do the call now, or fail if we didn't get an opcode, or
* enough of an opcode.
*/
- if (ioctlp->ioctl.inCopied < sizeof(afs_int32))
+ if (ioctlp->ioctl.inCopied < sizeof(afs_int32))
return CM_ERROR_INVAL;
memcpy(&opcode, ioctlp->ioctl.inDatap, sizeof(afs_int32));
ioctlp->ioctl.inDatap += sizeof(afs_int32);
- osi_Log1(afsd_logp, "Ioctl opcode 0x%x", opcode);
-
+ osi_Log1(afsd_logp, "smb_IoctlPrepareRead opcode 0x%x", opcode);
/* check for opcode out of bounds */
- if (opcode < 0 || opcode >= SMB_IOCTL_MAXPROCS)
+ if (opcode < 0 || opcode >= SMB_IOCTL_MAXPROCS) {
+ osi_Log0(afsd_logp, "smb_IoctlPrepareRead - invalid opcode");
return CM_ERROR_TOOBIG;
+ }
/* check for no such proc */
procp = smb_ioctlProcsp[opcode];
- if (procp == NULL)
- return CM_ERROR_BADOP;
-
+ if (procp == NULL) {
+ osi_Log0(afsd_logp, "smb_IoctlPrepareRead - unassigned opcode");
+ return CM_ERROR_INVAL;
+ }
/* otherwise, make the call */
ioctlp->ioctl.outDatap += sizeof(afs_int32); /* reserve room for return code */
- code = (*procp)(ioctlp, userp);
-
- osi_Log1(afsd_logp, "Ioctl return code 0x%x", code);
+ code = (*procp)(ioctlp, userp, pflags);
+ osi_Log1(afsd_logp, "smb_IoctlPrepareRead operation returns code 0x%x", code);
/* copy in return code */
memcpy(ioctlp->ioctl.outAllocp, &code, sizeof(afs_int32));
+ } else if (!(ioctlp->ioctl.flags & CM_IOCTLFLAG_DATAOUT)) {
+ osi_Log0(afsd_logp, "Ioctl invalid state - dataout expected");
+ return CM_ERROR_INVAL;
}
+
return 0;
}
* a series of reads (or the very first call), then we start a new call.
* We also ensure that things are properly initialized for the start of a call.
*/
-void
+void
smb_IoctlPrepareWrite(smb_fid_t *fidp, smb_ioctl_t *ioctlp)
{
/* make sure the buffer(s) are allocated */
- if (!ioctlp->ioctl.inAllocp)
+ if (!ioctlp->ioctl.inAllocp)
ioctlp->ioctl.inAllocp = malloc(SMB_IOCTL_MAXDATA);
if (!ioctlp->ioctl.outAllocp)
ioctlp->ioctl.outAllocp = malloc(SMB_IOCTL_MAXDATA);
ioctlp->ioctl.inDatap = ioctlp->ioctl.inAllocp;
ioctlp->ioctl.outDatap = ioctlp->ioctl.outAllocp;
ioctlp->ioctl.flags |= CM_IOCTLFLAG_DATAIN;
+ ioctlp->ioctl.flags &= ~CM_IOCTLFLAG_DATAOUT;
}
-}
+}
/* called from smb_ReceiveCoreRead when we receive a read on the ioctl fid */
afs_int32
afs_int32 leftToCopy;
char *op;
afs_int32 code;
- cm_user_t *userp;
+ smb_user_t *uidp;
+ cm_user_t *userp = NULL;
+ smb_t *smbp;
+ int isSystem = 0;
iop = fidp->ioctlp;
count = smb_GetSMBParm(inp, 1);
- userp = smb_GetUserFromVCP(vcp, inp);
+
+ /* Get the user and determine if it is the local machine account */
+ smbp = (smb_t *) inp;
+ uidp = smb_FindUID(vcp, smbp->uid, 0);
+ if (uidp) {
+ if (uidp->unp) {
+ osi_Log3(afsd_logp, "Ioctl uid %d user %x name %s",
+ uidp->userID, userp,
+ osi_LogSaveClientString(afsd_logp, uidp->unp->name));
+ } else {
+ osi_Log2(afsd_logp, "Ioctl uid %d user %x no name",
+ uidp->userID, userp);
+ }
+ isSystem = smb_userIsLocalSystem(uidp);
+ userp = smb_GetUserFromUID(uidp);
+ if (uidp->unp) {
+ osi_Log3(afsd_logp, "smb_IoctlRead uid %d user %x name %s",
+ uidp->userID, userp,
+ osi_LogSaveClientString(afsd_logp, uidp->unp->name));
+ } else {
+ osi_Log2(afsd_logp, "smb_IoctlRead uid %d user %x no name",
+ uidp->userID, userp);
+ }
+ smb_ReleaseUID(uidp);
+ } else {
+ osi_Log1(afsd_logp, "smb_IoctlRead no uid user %x no name", userp);
+ return CM_ERROR_BADSMB;
+ }
+
+ if (!userp) {
+ userp = cm_rootUserp;
+ cm_HoldUser(userp);
+ }
/* Identify tree */
code = smb_LookupTIDPath(vcp, ((smb_t *)inp)->tid, &iop->tidPathp);
- if(code) {
+ if (code) {
cm_ReleaseUser(userp);
return CM_ERROR_NOSUCHPATH;
}
/* turn the connection around, if required */
- code = smb_IoctlPrepareRead(fidp, iop, userp);
+ code = smb_IoctlPrepareRead(fidp, iop, userp, isSystem ? AFSCALL_FLAG_LOCAL_SYSTEM : 0);
if (code) {
cm_ReleaseUser(userp);
}
leftToCopy = (afs_int32)((iop->ioctl.outDatap - iop->ioctl.outAllocp) - iop->ioctl.outCopied);
+ if (leftToCopy < 0) {
+ osi_Log0(afsd_logp, "smb_IoctlRead leftToCopy went negative");
+ cm_ReleaseUser(userp);
+ return CM_ERROR_INVAL;
+ }
if (count > leftToCopy)
count = leftToCopy;
code = 0;
count = smb_GetSMBParm(inp, 1);
iop = fidp->ioctlp;
-
+
smb_IoctlPrepareWrite(fidp, iop);
op = smb_GetSMBData(inp, NULL);
op = smb_ParseDataBlock(op, NULL, &inDataBlockCount);
-
+
if (count + iop->ioctl.inCopied > SMB_IOCTL_MAXDATA) {
code = CM_ERROR_TOOBIG;
goto done;
}
-
+
/* copy data */
memcpy(iop->ioctl.inDatap + iop->ioctl.inCopied, op, count);
-
+
/* adjust counts */
iop->ioctl.inCopied += count;
}
return code;
-}
+}
/* called from smb_ReceiveV3WriteX when we receive a write call on the IOCTL
* file descriptor.
code = CM_ERROR_TOOBIG;
goto done;
}
-
+
/* copy data */
memcpy(iop->ioctl.inDatap + iop->ioctl.inCopied, op, count);
}
return code;
-}
+}
/* called from V3 read to handle IOCTL descriptor reads */
smb_IoctlV3Read(smb_fid_t *fidp, smb_vc_t *vcp, smb_packet_t *inp, smb_packet_t *outp)
{
smb_ioctl_t *iop;
- long count;
+ unsigned short count;
afs_int32 code;
long leftToCopy;
char *op;
cm_user_t *userp;
smb_user_t *uidp;
+ int isSystem = 0;
iop = fidp->ioctlp;
count = smb_GetSMBParm(inp, 5);
-
+
+ /* Get the user and determine if it is the local machine account */
uidp = smb_FindUID(vcp, ((smb_t *)inp)->uid, 0);
- userp = smb_GetUserFromUID(uidp);
- osi_assertx(userp != NULL, "null cm_user_t");
- iop->uidp = uidp;
- if (uidp && uidp->unp) {
- osi_Log3(afsd_logp, "Ioctl uid %d user %x name %S",
- uidp->userID, userp,
- osi_LogSaveClientString(afsd_logp, uidp->unp->name));
- } else {
- if (uidp)
- osi_Log2(afsd_logp, "Ioctl uid %d user %x no name",
- uidp->userID, userp);
- else
- osi_Log1(afsd_logp, "Ioctl no uid user %x no name",
- userp);
+ if (uidp) {
+ isSystem = smb_userIsLocalSystem(uidp);
+ userp = smb_GetUserFromUID(uidp);
+ if (uidp->unp) {
+ osi_Log3(afsd_logp, "smb_IoctlV3Read uid %d user %x name %s",
+ uidp->userID, userp,
+ osi_LogSaveClientString(afsd_logp, uidp->unp->name));
+ } else {
+ osi_Log2(afsd_logp, "smb_IoctlV3Read uid %d user %x no name",
+ uidp->userID, userp);
+ }
+ } else {
+ osi_Log0(afsd_logp, "smb_IoctlV3Read no uid");
+ return CM_ERROR_BADSMB;
+ }
+
+ if (!userp) {
+ userp = cm_rootUserp;
+ cm_HoldUser(userp);
}
+ iop->uidp = uidp;
+
code = smb_LookupTIDPath(vcp, ((smb_t *)inp)->tid, &iop->tidPathp);
if (code) {
if (uidp)
return CM_ERROR_NOSUCHPATH;
}
- code = smb_IoctlPrepareRead(fidp, iop, userp);
+ code = smb_IoctlPrepareRead(fidp, iop, userp, isSystem ? AFSCALL_FLAG_LOCAL_SYSTEM : 0);
if (uidp) {
iop->uidp = 0;
smb_ReleaseUID(uidp);
}
leftToCopy = (long)((iop->ioctl.outDatap - iop->ioctl.outAllocp) - iop->ioctl.outCopied);
- if (count > leftToCopy)
- count = leftToCopy;
-
+ if (leftToCopy < 0) {
+ osi_Log0(afsd_logp, "smb_IoctlV3Read leftToCopy went negative");
+ cm_ReleaseUser(userp);
+ return CM_ERROR_INVAL;
+ }
+ if (count > leftToCopy)
+ count = (unsigned short)leftToCopy;
+
/* 0 and 1 are reserved for request chaining, were setup by our caller,
* and will be further filled in after we return.
*/
* know where the data really is.
*/
op = smb_GetSMBData(outp, NULL);
-
+
/* now fill in offset from start of SMB header to first data byte (to op) */
smb_SetSMBParm(outp, 6, ((int) (op - outp->data)));
/* set the packet data length the count of the # of bytes */
smb_SetSMBDataLength(outp, count);
-
+
/* now copy the data into the response packet */
memcpy(op, iop->ioctl.outCopied + iop->ioctl.outAllocp, count);
cm_ReleaseUser(userp);
return 0;
-}
+}
/* called from Read Raw to handle IOCTL descriptor reads */
afs_int32
afs_int32 code;
cm_user_t *userp;
smb_user_t *uidp;
+ int isSystem = 0;
iop = fidp->ioctlp;
- userp = smb_GetUserFromVCP(vcp, inp);
-
- /* Log the user */
+ /* Get the user and determine if it is the local machine account */
uidp = smb_FindUID(vcp, ((smb_t *)inp)->uid, 0);
- if (uidp && uidp->unp) {
- osi_Log3(afsd_logp, "Ioctl uid %d user %x name %s",
- uidp->userID, userp,
- osi_LogSaveClientString(afsd_logp, uidp->unp->name));
- } else if (uidp) {
- osi_Log2(afsd_logp, "Ioctl uid %d user %x no name",
- uidp->userID, userp);
+ if (uidp) {
+ isSystem = smb_userIsLocalSystem(uidp);
+ userp = smb_GetUserFromUID(uidp);
+ if (uidp->unp) {
+ osi_Log3(afsd_logp, "smb_IoctlRawRead uid %d user %x name %s",
+ uidp->userID, userp,
+ osi_LogSaveClientString(afsd_logp, uidp->unp->name));
+ } else {
+ osi_Log2(afsd_logp, "smb_IoctlRawRead uid %d user %x no name",
+ uidp->userID, userp);
+ }
+ smb_ReleaseUID(uidp);
} else {
- osi_Log1(afsd_logp, "Ioctl no uid user %x no name",
- userp);
+ osi_Log0(afsd_logp, "smb_IoctlRawRead no uid");
+ }
+
+ if (!userp) {
+ userp = cm_rootUserp;
+ cm_HoldUser(userp);
}
- if (uidp)
- smb_ReleaseUID(uidp);
code = smb_LookupTIDPath(vcp, ((smb_t *)inp)->tid, &iop->tidPathp);
if (code) {
goto done;
}
- code = smb_IoctlPrepareRead(fidp, iop, userp);
+ code = smb_IoctlPrepareRead(fidp, iop, userp, isSystem ? AFSCALL_FLAG_LOCAL_SYSTEM : 0);
if (code) {
goto done;
}
leftToCopy = (long)((iop->ioctl.outDatap - iop->ioctl.outAllocp) - iop->ioctl.outCopied);
+ if (leftToCopy < 0) {
+ osi_Log0(afsd_logp, "smb_IoctlReadRaw leftToCopy went negative");
+ code = CM_ERROR_INVAL;
+ goto done;
+ }
ncbp = outp->ncbp;
- memset((char *)ncbp, 0, sizeof(NCB));
+ memset(ncbp, 0, sizeof(NCB));
ncbp->ncb_length = (unsigned short) leftToCopy;
ncbp->ncb_lsn = (unsigned char) vcp->lsn;
}
if (relativePath[0] == relativePath[1] &&
- relativePath[1] == '\\' &&
+ relativePath[1] == '\\' &&
!cm_ClientStrCmpNI(cm_NetbiosNameC, relativePath+2,
- cm_ClientStrLen(cm_NetbiosNameC)))
+ (int)cm_ClientStrLen(cm_NetbiosNameC)))
{
clientchar_t shareName[256];
clientchar_t *sharePath;
int shareFound, i;
- /* We may have found a UNC path.
+ /* We may have found a UNC path.
* If the first component is the NetbiosName,
* then throw out the second component (the submount)
* since it had better expand into the value of ioctl->tidPathp
shareFound = smb_FindShare(ioctlp->fidp->vcp, ioctlp->uidp, shareName, &sharePath);
if ( shareFound ) {
/* we found a sharename, therefore use the resulting path */
- code = cm_NameI(cm_data.rootSCachep, ioctlp->prefix->wdata,
+ code = cm_NameI(cm_RootSCachep(userp, reqp), ioctlp->prefix->wdata,
CM_FLAG_CASEFOLD | CM_FLAG_FOLLOW,
userp, sharePath, reqp, &substRootp);
free(sharePath);
}
} else {
/* otherwise, treat the name as a cellname mounted off the afs root.
- * This requires that we reconstruct the shareName string with
+ * This requires that we reconstruct the shareName string with
* leading and trailing slashes.
*/
p = relativePath + 2 + cm_ClientStrLen(cm_NetbiosNameC) + 1;
shareName[i] = 0; /* terminate string */
- code = cm_NameI(cm_data.rootSCachep, ioctlp->prefix->wdata,
+ code = cm_NameI(cm_RootSCachep(userp, reqp), ioctlp->prefix->wdata,
CM_FLAG_CASEFOLD | CM_FLAG_FOLLOW,
userp, shareName, reqp, &substRootp);
if (code) {
}
}
} else {
- code = cm_NameI(cm_data.rootSCachep, ioctlp->prefix->wdata,
+ code = cm_NameI(cm_RootSCachep(userp, reqp), ioctlp->prefix->wdata,
CM_FLAG_CASEFOLD | CM_FLAG_FOLLOW,
userp, ioctlp->tidPathp, reqp, &substRootp);
if (code) {
free(relativePath);
return code;
}
-
+
lastComponent = cm_ClientStrRChr(relativePath, '\\');
if (lastComponent && (lastComponent - relativePath) > 1 &&
cm_ClientStrLen(lastComponent) > 1) {
if (substRootp)
cm_ReleaseSCache(substRootp);
- /* and return success */
- osi_Log1(afsd_logp,"cm_ParseIoctlPath [8] code 0x%x", code);
-
if (relativePath)
free(relativePath);
+
+ /* Ensure that the status object is up to date */
+ lock_ObtainWrite(&(*scpp)->rw);
+ code = cm_SyncOp( *scpp, NULL, userp, reqp, 0,
+ CM_SCACHESYNC_NEEDCALLBACK | CM_SCACHESYNC_GETSTATUS);
+ if (code == 0)
+ cm_SyncOpDone( *scpp, NULL, CM_SCACHESYNC_NEEDCALLBACK | CM_SCACHESYNC_GETSTATUS);
+ lock_ReleaseWrite(&(*scpp)->rw);
+
+ /* and return success */
+ osi_Log1(afsd_logp,"cm_ParseIoctlPath [8] code 0x%x", code);
return 0;
}
}
else {
*tp = 0;
- if (leafp)
+ if (leafp)
cm_ClientStrCpy(leafp, LEAF_SIZE, tp+1);
}
inpathp = NULL; /* We don't need this from this point on */
if (tbuffer[0] == tbuffer[1] &&
- tbuffer[1] == '\\' &&
+ tbuffer[1] == '\\' &&
!cm_ClientStrCmpNI(cm_NetbiosNameC, tbuffer+2,
- cm_ClientStrLen(cm_NetbiosNameC)))
+ (int)cm_ClientStrLen(cm_NetbiosNameC)))
{
clientchar_t shareName[256];
clientchar_t *sharePath;
int shareFound, i;
- /* We may have found a UNC path.
+ /* We may have found a UNC path.
* If the first component is the NetbiosName,
* then throw out the second component (the submount)
* since it had better expand into the value of ioctl->tidPathp
shareFound = smb_FindShare(ioctlp->fidp->vcp, ioctlp->uidp, shareName, &sharePath);
if ( shareFound ) {
/* we found a sharename, therefore use the resulting path */
- code = cm_NameI(cm_data.rootSCachep, ioctlp->prefix->wdata,
+ code = cm_NameI(cm_RootSCachep(userp, reqp), ioctlp->prefix->wdata,
CM_FLAG_CASEFOLD | CM_FLAG_FOLLOW,
userp, sharePath, reqp, &substRootp);
free(sharePath);
if (code) return code;
} else {
/* otherwise, treat the name as a cellname mounted off the afs root.
- * This requires that we reconstruct the shareName string with
+ * This requires that we reconstruct the shareName string with
* leading and trailing slashes.
*/
p = tbuffer + 2 + cm_ClientStrLen(cm_NetbiosNameC) + 1;
shareName[i++] = '/'; /* add trailing slash */
shareName[i] = 0; /* terminate string */
- code = cm_NameI(cm_data.rootSCachep, ioctlp->prefix->wdata,
+ code = cm_NameI(cm_RootSCachep(userp, reqp), ioctlp->prefix->wdata,
CM_FLAG_CASEFOLD | CM_FLAG_FOLLOW,
userp, shareName, reqp, &substRootp);
if (code) return code;
if (code) return code;
}
} else {
- code = cm_NameI(cm_data.rootSCachep, ioctlp->prefix->wdata,
+ code = cm_NameI(cm_RootSCachep(userp, reqp), ioctlp->prefix->wdata,
CM_FLAG_CASEFOLD | CM_FLAG_FOLLOW,
userp, ioctlp->tidPathp, reqp, &substRootp);
if (code) return code;
code = (long)strlen(ioctlp->ioctl.inDatap) + 1;
ioctlp->ioctl.inDatap += code;
+ /* Ensure that the status object is up to date */
+ lock_ObtainWrite(&(*scpp)->rw);
+ code = cm_SyncOp( *scpp, NULL, userp, reqp, 0,
+ CM_SCACHESYNC_NEEDCALLBACK | CM_SCACHESYNC_GETSTATUS);
+ if (code == 0)
+ cm_SyncOpDone( *scpp, NULL, CM_SCACHESYNC_NEEDCALLBACK | CM_SCACHESYNC_GETSTATUS);
+ lock_ReleaseWrite(&(*scpp)->rw);
+
/* and return success */
return 0;
}
-afs_int32
-smb_IoctlSetToken(struct smb_ioctl *ioctlp, struct cm_user *userp)
+afs_int32
+smb_IoctlSetToken(struct smb_ioctl *ioctlp, struct cm_user *userp, afs_uint32 pflags)
{
char *saveDataPtr;
char *tp;
clientchar_t *uname = NULL;
clientchar_t *smbname = NULL;
clientchar_t *wdir = NULL;
+ clientchar_t *rpc_sid = NULL;
afs_int32 code = 0;
saveDataPtr = ioctlp->ioctl.inDatap;
if (flags & PIOCTL_LOGON) {
/* SMB user name with which to associate tokens */
smbname = cm_ParseIoctlStringAlloc(&ioctlp->ioctl, tp);
- osi_Log2(smb_logp,"cm_IoctlSetToken for user [%S] smbname [%S]",
+ osi_Log2(smb_logp,"smb_IoctlSetToken for user [%S] smbname [%S]",
osi_LogSaveClientString(smb_logp,uname),
osi_LogSaveClientString(smb_logp,smbname));
fprintf(stderr, "SMB name = %S\n", smbname);
tp += strlen(tp) + 1;
} else {
- osi_Log1(smb_logp,"cm_IoctlSetToken for user [%S]",
+ osi_Log1(smb_logp,"smb_IoctlSetToken for user [%S]",
osi_LogSaveClientString(smb_logp, uname));
}
/* uuid */
memcpy(&uuid, tp, sizeof(uuid));
- if (!cm_FindTokenEvent(uuid, sessionKey)) {
+ if (!cm_FindTokenEvent(uuid, sessionKey, &rpc_sid)) {
code = CM_ERROR_INVAL;
goto done;
}
+
+ if (rpc_sid) {
+ if (!(pflags & AFSCALL_FLAG_LOCAL_SYSTEM)) {
+ osi_Log1(smb_logp,"smb_IoctlSetToken Rpc Sid [%S]",
+ osi_LogSaveClientString(smb_logp, rpc_sid));
+ if (!cm_ClientStrCmp(NTSID_LOCAL_SYSTEM, rpc_sid))
+ pflags |= AFSCALL_FLAG_LOCAL_SYSTEM;
+ }
+ LocalFree(rpc_sid);
+ }
+
+ if (!(pflags & AFSCALL_FLAG_LOCAL_SYSTEM) && (flags & PIOCTL_LOGON)) {
+ code = CM_ERROR_NOACCESS;
+ goto done;
+ }
} else {
cellp = cm_data.rootCellp;
- osi_Log0(smb_logp,"cm_IoctlSetToken - no name specified");
+ osi_Log0(smb_logp,"smb_IoctlSetToken - no name specified");
}
- if (flags & PIOCTL_LOGON) {
- userp = smb_FindCMUserByName(smbname, ioctlp->fidp->vcp->rname,
- SMB_FLAG_CREATE|SMB_FLAG_AFSLOGON);
- release_userp = 1;
+ if ((pflags & AFSCALL_FLAG_LOCAL_SYSTEM) && (flags & PIOCTL_LOGON)) {
+ PSID pSid = NULL;
+ DWORD dwSize1 = 0, dwSize2 = 0;
+ wchar_t *pszRefDomain = NULL;
+ SID_NAME_USE snu = SidTypeGroup;
+ clientchar_t * secSidString = NULL;
+ DWORD gle;
+
+ /*
+ * The specified smbname is may not be a SID for the user.
+ * See if we can obtain the SID for the specified name.
+ * If we can, use that instead of the name provided.
+ */
+
+ LookupAccountNameW( NULL /* System Name to begin Search */,
+ smbname,
+ NULL, &dwSize1,
+ NULL, &dwSize2,
+ &snu);
+ gle = GetLastError();
+ if (gle == ERROR_INSUFFICIENT_BUFFER) {
+ pSid = LocalAlloc(LMEM_FIXED | LMEM_ZEROINIT, dwSize1);
+ /*
+ * Although dwSize2 is supposed to include the terminating
+ * NUL character, on Win7 it does not.
+ */
+ pszRefDomain = malloc((dwSize2 + 1) * sizeof(wchar_t));
+ }
+
+ if ( pSid && pszRefDomain ) {
+ if (LookupAccountNameW( NULL /* System Name to begin Search */,
+ smbname,
+ pSid, &dwSize1,
+ pszRefDomain, &dwSize2,
+ &snu))
+ ConvertSidToStringSidW(pSid, &secSidString);
+ }
+
+ if (secSidString) {
+ userp = smb_FindCMUserBySID( secSidString, ioctlp->fidp->vcp->rname,
+ SMB_FLAG_CREATE|SMB_FLAG_AFSLOGON);
+ LocalFree(secSidString);
+ } else {
+ /* Free the SID so we can reuse the variable */
+ if (pSid) {
+ LocalFree(pSid);
+ pSid = NULL;
+ }
+
+ /*
+ * If the SID for the name could not be found,
+ * perhaps it already is a SID
+ */
+ if (!ConvertStringSidToSidW( smbname, &pSid)) {
+ userp = smb_FindCMUserBySID( smbname, ioctlp->fidp->vcp->rname,
+ SMB_FLAG_CREATE|SMB_FLAG_AFSLOGON);
+ } else {
+ userp = smb_FindCMUserByName( smbname, ioctlp->fidp->vcp->rname,
+ SMB_FLAG_CREATE|SMB_FLAG_AFSLOGON);
+ }
+ }
+
+ if (pSid)
+ LocalFree(pSid);
+ if (pszRefDomain)
+ free(pszRefDomain);
+
+ release_userp = 1;
}
/* store the token */
lock_ObtainMutex(&userp->mx);
ucellp = cm_GetUCell(userp, cellp);
- osi_Log1(smb_logp,"cm_IoctlSetToken ucellp %lx", ucellp);
+ osi_Log1(smb_logp,"smb_IoctlSetToken ucellp %lx", ucellp);
ucellp->ticketLen = ticketLen;
if (ucellp->ticketp)
free(ucellp->ticketp); /* Discard old token if any */
cm_UsernameToId(uname, ucellp, &ucellp->uid);
#endif
}
- ucellp->flags |= CM_UCELLFLAG_RXKAD;
+ _InterlockedOr(&ucellp->flags, CM_UCELLFLAG_RXKAD);
lock_ReleaseMutex(&userp->mx);
- if (flags & PIOCTL_LOGON) {
+ if ((pflags & AFSCALL_FLAG_LOCAL_SYSTEM) && (flags & PIOCTL_LOGON)) {
ioctlp->ioctl.flags |= CM_IOCTLFLAG_LOGON;
}
- cm_ResetACLCache(userp);
+ cm_ResetACLCache(cellp, userp);
done:
+ SecureZeroMemory(sessionKey, sizeof(sessionKey));
+
if (release_userp)
cm_ReleaseUser(userp);
afs_int32
-smb_IoctlGetSMBName(smb_ioctl_t *ioctlp, cm_user_t *userp)
+smb_IoctlGetSMBName(smb_ioctl_t *ioctlp, cm_user_t *userp, afs_uint32 pflags)
{
smb_user_t *uidp = ioctlp->uidp;
int cch;
cch = cm_ClientStringToUtf8(uidp->unp->name,
- cm_ClientStrLen(uidp->unp->name),
-
+ -1,
ioctlp->ioctl.outDatap,
- (SMB_IOCTL_MAXDATA -
+ (int)(SMB_IOCTL_MAXDATA -
(ioctlp->ioctl.outDatap - ioctlp->ioctl.outAllocp))
/ sizeof(cm_utf8char_t));
return 0;
}
-afs_int32
-smb_IoctlGetACL(smb_ioctl_t *ioctlp, cm_user_t *userp)
+afs_int32
+smb_IoctlGetACL(smb_ioctl_t *ioctlp, cm_user_t *userp, afs_uint32 pflags)
{
cm_scache_t *scp;
afs_int32 code;
if (optionsp && CM_IOCTL_QOPTS_HAVE_FID(optionsp)) {
cm_fid_t fid;
cm_SkipIoctlPath(&ioctlp->ioctl);
- cm_SetFid(&fid, optionsp->fid.cell, optionsp->fid.volume,
+ cm_SetFid(&fid, optionsp->fid.cell, optionsp->fid.volume,
optionsp->fid.vnode, optionsp->fid.unique);
code = cm_GetSCache(&fid, &scp, userp, &req);
} else {
code = smb_ParseIoctlPath(ioctlp, userp, &req, &scp, flags);
}
- if (code)
+
+ if (code)
return code;
code = cm_IoctlGetACL(&ioctlp->ioctl, userp, scp, &req);
return code;
}
-afs_int32
-smb_IoctlSetACL(smb_ioctl_t *ioctlp, cm_user_t *userp)
+afs_int32
+smb_IoctlSetACL(smb_ioctl_t *ioctlp, cm_user_t *userp, afs_uint32 pflags)
{
cm_scache_t *scp;
afs_int32 code;
smb_InitReq(&req);
code = smb_ParseIoctlPath(ioctlp, userp, &req, &scp, flags);
- if (code)
+ if (code)
return code;
code = cm_IoctlSetACL(&ioctlp->ioctl, userp, scp, &req);
}
afs_int32
-smb_IoctlGetFileCellName(struct smb_ioctl *ioctlp, struct cm_user *userp)
+smb_IoctlGetFileCellName(struct smb_ioctl *ioctlp, struct cm_user *userp, afs_uint32 pflags)
{
afs_int32 code;
cm_scache_t *scp;
if (optionsp && CM_IOCTL_QOPTS_HAVE_FID(optionsp)) {
cm_fid_t fid;
cm_SkipIoctlPath(&ioctlp->ioctl);
- cm_SetFid(&fid, optionsp->fid.cell, optionsp->fid.volume,
+ cm_SetFid(&fid, optionsp->fid.cell, optionsp->fid.volume,
optionsp->fid.vnode, optionsp->fid.unique);
code = cm_GetSCache(&fid, &scp, userp, &req);
} else {
code = smb_ParseIoctlPath(ioctlp, userp, &req, &scp, flags);
}
- if (code)
+ if (code)
return code;
code = cm_IoctlGetFileCellName(&ioctlp->ioctl, userp, scp, &req);
return code;
}
-afs_int32
-smb_IoctlFlushAllVolumes(struct smb_ioctl *ioctlp, struct cm_user *userp)
+afs_int32
+smb_IoctlFlushAllVolumes(struct smb_ioctl *ioctlp, struct cm_user *userp, afs_uint32 pflags)
{
cm_req_t req;
return cm_IoctlFlushAllVolumes(&ioctlp->ioctl, userp, &req);
}
-afs_int32
-smb_IoctlFlushVolume(struct smb_ioctl *ioctlp, struct cm_user *userp)
+afs_int32
+smb_IoctlFlushVolume(struct smb_ioctl *ioctlp, struct cm_user *userp, afs_uint32 pflags)
{
afs_int32 code;
cm_scache_t *scp;
if (optionsp && CM_IOCTL_QOPTS_HAVE_FID(optionsp)) {
cm_fid_t fid;
cm_SkipIoctlPath(&ioctlp->ioctl);
- cm_SetFid(&fid, optionsp->fid.cell, optionsp->fid.volume,
+ cm_SetFid(&fid, optionsp->fid.cell, optionsp->fid.volume,
optionsp->fid.vnode, optionsp->fid.unique);
code = cm_GetSCache(&fid, &scp, userp, &req);
} else {
code = smb_ParseIoctlPath(ioctlp, userp, &req, &scp, flags);
}
- if (code)
+ if (code)
return code;
code = cm_IoctlFlushVolume(&ioctlp->ioctl, userp, scp, &req);
return code;
}
-afs_int32
-smb_IoctlFlushFile(struct smb_ioctl *ioctlp, struct cm_user *userp)
+afs_int32
+smb_IoctlFlushFile(struct smb_ioctl *ioctlp, struct cm_user *userp, afs_uint32 pflags)
{
afs_int32 code;
cm_scache_t *scp;
} else {
code = smb_ParseIoctlPath(ioctlp, userp, &req, &scp, flags);
}
- if (code)
+ if (code)
return code;
code = cm_IoctlFlushFile(&ioctlp->ioctl, userp, scp, &req);
return code;
}
-afs_int32
-smb_IoctlSetVolumeStatus(struct smb_ioctl *ioctlp, struct cm_user *userp)
+afs_int32
+smb_IoctlSetVolumeStatus(struct smb_ioctl *ioctlp, struct cm_user *userp, afs_uint32 pflags)
{
afs_int32 code;
cm_scache_t *scp;
return code;
}
-afs_int32
-smb_IoctlGetVolumeStatus(struct smb_ioctl *ioctlp, struct cm_user *userp)
+afs_int32
+smb_IoctlGetVolumeStatus(struct smb_ioctl *ioctlp, struct cm_user *userp, afs_uint32 pflags)
{
afs_int32 code;
cm_scache_t *scp;
if (optionsp && CM_IOCTL_QOPTS_HAVE_FID(optionsp)) {
cm_fid_t fid;
cm_SkipIoctlPath(&ioctlp->ioctl);
- cm_SetFid(&fid, optionsp->fid.cell, optionsp->fid.volume,
+ cm_SetFid(&fid, optionsp->fid.cell, optionsp->fid.volume,
optionsp->fid.vnode, optionsp->fid.unique);
code = cm_GetSCache(&fid, &scp, userp, &req);
} else {
code = smb_ParseIoctlPath(ioctlp, userp, &req, &scp, flags);
}
- if (code)
+ if (code)
return code;
code = cm_IoctlGetVolumeStatus(&ioctlp->ioctl, userp, scp, &req);
return code;
}
-afs_int32
-smb_IoctlGetFid(struct smb_ioctl *ioctlp, struct cm_user *userp)
+afs_int32
+smb_IoctlGetFid(struct smb_ioctl *ioctlp, struct cm_user *userp, afs_uint32 pflags)
{
afs_int32 code;
cm_scache_t *scp;
flags |= (optionsp->literal ? CM_PARSE_FLAG_LITERAL : 0);
code = smb_ParseIoctlPath(ioctlp, userp, &req, &scp, flags);
- if (code)
+ if (code)
return code;
code = cm_IoctlGetFid(&ioctlp->ioctl, userp, scp, &req);
return code;
}
-afs_int32
-smb_IoctlGetFileType(struct smb_ioctl *ioctlp, struct cm_user *userp)
+afs_int32
+smb_IoctlGetFileType(struct smb_ioctl *ioctlp, struct cm_user *userp, afs_uint32 pflags)
{
afs_int32 code;
cm_scache_t *scp;
if (optionsp && CM_IOCTL_QOPTS_HAVE_FID(optionsp)) {
cm_fid_t fid;
cm_SkipIoctlPath(&ioctlp->ioctl);
- cm_SetFid(&fid, optionsp->fid.cell, optionsp->fid.volume,
+ cm_SetFid(&fid, optionsp->fid.cell, optionsp->fid.volume,
optionsp->fid.vnode, optionsp->fid.unique);
code = cm_GetSCache(&fid, &scp, userp, &req);
} else {
code = smb_ParseIoctlPath(ioctlp, userp, &req, &scp, flags);
}
- if (code)
+ if (code)
return code;
code = cm_IoctlGetFileType(&ioctlp->ioctl, userp, scp, &req);
return code;
}
-afs_int32
-smb_IoctlGetOwner(struct smb_ioctl *ioctlp, struct cm_user *userp)
+afs_int32
+smb_IoctlGetOwner(struct smb_ioctl *ioctlp, struct cm_user *userp, afs_uint32 pflags)
{
afs_int32 code;
cm_scache_t *scp;
} else {
code = smb_ParseIoctlPath(ioctlp, userp, &req, &scp, flags);
}
- if (code)
+ if (code)
return code;
code = cm_IoctlGetOwner(&ioctlp->ioctl, userp, scp, &req);
return code;
}
-afs_int32
-smb_IoctlWhereIs(struct smb_ioctl *ioctlp, struct cm_user *userp)
+afs_int32
+smb_IoctlWhereIs(struct smb_ioctl *ioctlp, struct cm_user *userp, afs_uint32 pflags)
{
afs_int32 code;
cm_scache_t *scp;
} else {
code = smb_ParseIoctlPath(ioctlp, userp, &req, &scp, flags);
}
- if (code)
+ if (code)
return code;
code = cm_IoctlWhereIs(&ioctlp->ioctl, userp, scp, &req);
}
-afs_int32
-smb_IoctlStatMountPoint(struct smb_ioctl *ioctlp, struct cm_user *userp)
+afs_int32
+smb_IoctlStatMountPoint(struct smb_ioctl *ioctlp, struct cm_user *userp, afs_uint32 pflags)
{
afs_int32 code;
cm_scache_t *dscp;
return code;
}
-afs_int32
-smb_IoctlDeleteMountPoint(struct smb_ioctl *ioctlp, struct cm_user *userp)
+afs_int32
+smb_IoctlDeleteMountPoint(struct smb_ioctl *ioctlp, struct cm_user *userp, afs_uint32 pflags)
{
afs_int32 code;
cm_scache_t *dscp;
smb_InitReq(&req);
code = smb_ParseIoctlPath(ioctlp, userp, &req, &dscp, 0);
- if (code)
+ if (code)
return code;
code = cm_IoctlDeleteMountPoint(&ioctlp->ioctl, userp, dscp, &req);
return code;
}
-afs_int32
-smb_IoctlCheckServers(struct smb_ioctl *ioctlp, struct cm_user *userp)
+afs_int32
+smb_IoctlCheckServers(struct smb_ioctl *ioctlp, struct cm_user *userp, afs_uint32 pflags)
{
cm_SkipIoctlPath(&ioctlp->ioctl); /* we don't care about the path */
return cm_IoctlCheckServers(&ioctlp->ioctl, userp);
}
-afs_int32
-smb_IoctlGag(struct smb_ioctl *ioctlp, struct cm_user *userp)
+afs_int32
+smb_IoctlGag(struct smb_ioctl *ioctlp, struct cm_user *userp, afs_uint32 pflags)
{
/* we don't print anything superfluous, so we don't support the gag call */
return CM_ERROR_INVAL;
}
-afs_int32
-smb_IoctlCheckVolumes(struct smb_ioctl *ioctlp, struct cm_user *userp)
+afs_int32
+smb_IoctlCheckVolumes(struct smb_ioctl *ioctlp, struct cm_user *userp, afs_uint32 pflags)
{
cm_SkipIoctlPath(&ioctlp->ioctl);
return cm_IoctlCheckVolumes(&ioctlp->ioctl, userp);
}
-afs_int32 smb_IoctlSetCacheSize(struct smb_ioctl *ioctlp, struct cm_user *userp)
+afs_int32 smb_IoctlSetCacheSize(struct smb_ioctl *ioctlp, struct cm_user *userp, afs_uint32 pflags)
{
cm_SkipIoctlPath(&ioctlp->ioctl);
}
-afs_int32
-smb_IoctlTraceControl(struct smb_ioctl *ioctlp, struct cm_user *userp)
+afs_int32
+smb_IoctlTraceControl(struct smb_ioctl *ioctlp, struct cm_user *userp, afs_uint32 pflags)
{
cm_SkipIoctlPath(&ioctlp->ioctl);
-
+
return cm_IoctlTraceControl(&ioctlp->ioctl, userp);
}
-afs_int32
-smb_IoctlGetCacheParms(struct smb_ioctl *ioctlp, struct cm_user *userp)
+afs_int32
+smb_IoctlGetCacheParms(struct smb_ioctl *ioctlp, struct cm_user *userp, afs_uint32 pflags)
{
cm_SkipIoctlPath(&ioctlp->ioctl);
-
+
return cm_IoctlGetCacheParms(&ioctlp->ioctl, userp);
}
-afs_int32
-smb_IoctlGetCell(struct smb_ioctl *ioctlp, struct cm_user *userp)
+afs_int32
+smb_IoctlGetCell(struct smb_ioctl *ioctlp, struct cm_user *userp, afs_uint32 pflags)
{
cm_SkipIoctlPath(&ioctlp->ioctl);
return cm_IoctlGetCell(&ioctlp->ioctl, userp);
}
-afs_int32
-smb_IoctlNewCell(struct smb_ioctl *ioctlp, struct cm_user *userp)
+afs_int32
+smb_IoctlNewCell(struct smb_ioctl *ioctlp, struct cm_user *userp, afs_uint32 pflags)
{
cm_SkipIoctlPath(&ioctlp->ioctl);
return cm_IoctlNewCell(&ioctlp->ioctl, userp);
}
-afs_int32
-smb_IoctlGetWsCell(smb_ioctl_t *ioctlp, cm_user_t *userp)
+afs_int32
+smb_IoctlNewCell2(struct smb_ioctl *ioctlp, struct cm_user *userp, afs_uint32 pflags)
+{
+ cm_SkipIoctlPath(&ioctlp->ioctl);
+
+ return cm_IoctlNewCell2(&ioctlp->ioctl, userp);
+}
+
+afs_int32
+smb_IoctlGetWsCell(smb_ioctl_t *ioctlp, cm_user_t *userp, afs_uint32 pflags)
{
cm_SkipIoctlPath(&ioctlp->ioctl);
return cm_IoctlGetWsCell(&ioctlp->ioctl, userp);
}
-afs_int32
-smb_IoctlSysName(struct smb_ioctl *ioctlp, struct cm_user *userp)
+afs_int32
+smb_IoctlSysName(struct smb_ioctl *ioctlp, struct cm_user *userp, afs_uint32 pflags)
{
cm_SkipIoctlPath(&ioctlp->ioctl);
return cm_IoctlSysName(&ioctlp->ioctl, userp);
}
-afs_int32
-smb_IoctlGetCellStatus(struct smb_ioctl *ioctlp, struct cm_user *userp)
+afs_int32
+smb_IoctlGetCellStatus(struct smb_ioctl *ioctlp, struct cm_user *userp, afs_uint32 pflags)
{
cm_SkipIoctlPath(&ioctlp->ioctl);
return cm_IoctlGetCellStatus(&ioctlp->ioctl, userp);
}
-afs_int32
-smb_IoctlSetCellStatus(struct smb_ioctl *ioctlp, struct cm_user *userp)
+afs_int32
+smb_IoctlSetCellStatus(struct smb_ioctl *ioctlp, struct cm_user *userp, afs_uint32 pflags)
{
cm_SkipIoctlPath(&ioctlp->ioctl);
}
afs_int32
-smb_IoctlSetSPrefs(struct smb_ioctl *ioctlp, struct cm_user *userp)
+smb_IoctlSetSPrefs(struct smb_ioctl *ioctlp, struct cm_user *userp, afs_uint32 pflags)
{
cm_SkipIoctlPath(&ioctlp->ioctl);
}
afs_int32
-smb_IoctlGetSPrefs(struct smb_ioctl *ioctlp, struct cm_user *userp)
+smb_IoctlGetSPrefs(struct smb_ioctl *ioctlp, struct cm_user *userp, afs_uint32 pflags)
{
cm_SkipIoctlPath(&ioctlp->ioctl);
}
afs_int32
-smb_IoctlStoreBehind(struct smb_ioctl *ioctlp, struct cm_user *userp)
+smb_IoctlStoreBehind(struct smb_ioctl *ioctlp, struct cm_user *userp, afs_uint32 pflags)
{
/* we ignore default asynchrony since we only have one way
* of doing this today.
*/
return 0;
-}
+}
afs_int32
-smb_IoctlCreateMountPoint(struct smb_ioctl *ioctlp, struct cm_user *userp)
+smb_IoctlCreateMountPoint(struct smb_ioctl *ioctlp, struct cm_user *userp, afs_uint32 pflags)
{
afs_int32 code;
cm_scache_t *dscp;
cm_req_t req;
smb_InitReq(&req);
-
+
code = smb_ParseIoctlParent(ioctlp, userp, &req, &dscp, leaf);
if (code)
return code;
}
afs_int32
-smb_IoctlSymlink(struct smb_ioctl *ioctlp, struct cm_user *userp)
+smb_IoctlSymlink(struct smb_ioctl *ioctlp, struct cm_user *userp, afs_uint32 pflags)
{
afs_int32 code;
cm_scache_t *dscp;
return code;
}
-afs_int32
-smb_IoctlListlink(struct smb_ioctl *ioctlp, struct cm_user *userp)
+afs_int32
+smb_IoctlListlink(struct smb_ioctl *ioctlp, struct cm_user *userp, afs_uint32 pflags)
{
afs_int32 code;
cm_scache_t *dscp;
return code;
}
-afs_int32
-smb_IoctlIslink(struct smb_ioctl *ioctlp, struct cm_user *userp)
+afs_int32
+smb_IoctlIslink(struct smb_ioctl *ioctlp, struct cm_user *userp, afs_uint32 pflags)
{/*CHECK FOR VALID SYMLINK*/
afs_int32 code;
cm_scache_t *dscp;
return code;
}
-afs_int32
-smb_IoctlDeletelink(struct smb_ioctl *ioctlp, struct cm_user *userp)
+afs_int32
+smb_IoctlDeletelink(struct smb_ioctl *ioctlp, struct cm_user *userp, afs_uint32 pflags)
{
afs_int32 code;
cm_scache_t *dscp;
return code;
}
-afs_int32
-smb_IoctlGetTokenIter(struct smb_ioctl *ioctlp, struct cm_user *userp)
+afs_int32
+smb_IoctlGetTokenIter(struct smb_ioctl *ioctlp, struct cm_user *userp, afs_uint32 pflags)
{
cm_SkipIoctlPath(&ioctlp->ioctl);
}
afs_int32
-smb_IoctlGetToken(struct smb_ioctl *ioctlp, struct cm_user *userp)
+smb_IoctlGetToken(struct smb_ioctl *ioctlp, struct cm_user *userp, afs_uint32 pflags)
{
cm_SkipIoctlPath(&ioctlp->ioctl);
afs_int32
-smb_IoctlDelToken(struct smb_ioctl *ioctlp, struct cm_user *userp)
+smb_IoctlDelToken(struct smb_ioctl *ioctlp, struct cm_user *userp, afs_uint32 pflags)
{
cm_SkipIoctlPath(&ioctlp->ioctl);
afs_int32
-smb_IoctlDelAllToken(struct smb_ioctl *ioctlp, struct cm_user *userp)
+smb_IoctlDelAllToken(struct smb_ioctl *ioctlp, struct cm_user *userp, afs_uint32 pflags)
{
cm_SkipIoctlPath(&ioctlp->ioctl);
afs_int32
-smb_IoctlMakeSubmount(struct smb_ioctl *ioctlp, struct cm_user *userp)
+smb_IoctlMakeSubmount(struct smb_ioctl *ioctlp, struct cm_user *userp, afs_uint32 pflags)
{
cm_SkipIoctlPath(&ioctlp->ioctl);
}
afs_int32
-smb_IoctlGetRxkcrypt(struct smb_ioctl *ioctlp, struct cm_user *userp)
+smb_IoctlGetRxkcrypt(struct smb_ioctl *ioctlp, struct cm_user *userp, afs_uint32 pflags)
{
cm_SkipIoctlPath(&ioctlp->ioctl);
}
afs_int32
-smb_IoctlSetRxkcrypt(struct smb_ioctl *ioctlp, struct cm_user *userp)
+smb_IoctlSetRxkcrypt(struct smb_ioctl *ioctlp, struct cm_user *userp, afs_uint32 pflags)
{
cm_SkipIoctlPath(&ioctlp->ioctl);
}
afs_int32
-smb_IoctlRxStatProcess(struct smb_ioctl *ioctlp, struct cm_user *userp)
+smb_IoctlRxStatProcess(struct smb_ioctl *ioctlp, struct cm_user *userp, afs_uint32 pflags)
{
cm_SkipIoctlPath(&ioctlp->ioctl);
afs_int32
-smb_IoctlRxStatPeer(struct smb_ioctl *ioctlp, struct cm_user *userp)
+smb_IoctlRxStatPeer(struct smb_ioctl *ioctlp, struct cm_user *userp, afs_uint32 pflags)
{
cm_SkipIoctlPath(&ioctlp->ioctl);
}
afs_int32
-smb_IoctlUnicodeControl(struct smb_ioctl *ioctlp, struct cm_user *userp)
+smb_IoctlUnicodeControl(struct smb_ioctl *ioctlp, struct cm_user *userp, afs_uint32 pflags)
{
cm_SkipIoctlPath(&ioctlp->ioctl);
}
afs_int32
-smb_IoctlUUIDControl(struct smb_ioctl *ioctlp, struct cm_user *userp)
+smb_IoctlUUIDControl(struct smb_ioctl *ioctlp, struct cm_user *userp, afs_uint32 pflags)
{
cm_SkipIoctlPath(&ioctlp->ioctl);
afs_int32
-smb_IoctlMemoryDump(struct smb_ioctl *ioctlp, struct cm_user *userp)
+smb_IoctlMemoryDump(struct smb_ioctl *ioctlp, struct cm_user *userp, afs_uint32 pflags)
{
cm_SkipIoctlPath(&ioctlp->ioctl);
}
afs_int32
-smb_IoctlPathAvailability(struct smb_ioctl *ioctlp, struct cm_user *userp)
+smb_IoctlPathAvailability(struct smb_ioctl *ioctlp, struct cm_user *userp, afs_uint32 pflags)
{
afs_int32 code;
cm_scache_t *scp;
if (optionsp && CM_IOCTL_QOPTS_HAVE_FID(optionsp)) {
cm_fid_t fid;
cm_SkipIoctlPath(&ioctlp->ioctl);
- cm_SetFid(&fid, optionsp->fid.cell, optionsp->fid.volume,
+ cm_SetFid(&fid, optionsp->fid.cell, optionsp->fid.volume,
optionsp->fid.vnode, optionsp->fid.unique);
code = cm_GetSCache(&fid, &scp, userp, &req);
} else {
code = smb_ParseIoctlPath(ioctlp, userp, &req, &scp, flags);
}
- if (code)
+ if (code)
return code;
code = cm_IoctlPathAvailability(&ioctlp->ioctl, userp, scp, &req);
}
afs_int32
-smb_IoctlVolStatTest(struct smb_ioctl *ioctlp, struct cm_user *userp)
+smb_IoctlVolStatTest(struct smb_ioctl *ioctlp, struct cm_user *userp, afs_uint32 pflags)
{
cm_req_t req;
return cm_IoctlVolStatTest(&ioctlp->ioctl, userp, &req);
}
+
+/*
+ * VIOC_SETOWNER
+ *
+ * This pioctl requires the use of the cm_ioctlQueryOptions_t structure.
+ *
+ */
+afs_int32
+smb_IoctlSetOwner(struct smb_ioctl *ioctlp, struct cm_user *userp, afs_uint32 pflags)
+{
+ afs_int32 code;
+ cm_scache_t *scp;
+ cm_req_t req;
+ cm_ioctlQueryOptions_t *optionsp;
+ afs_uint32 flags = 0;
+
+ smb_InitReq(&req);
+
+ optionsp = cm_IoctlGetQueryOptions(&ioctlp->ioctl, userp);
+ if (optionsp) {
+ if (CM_IOCTL_QOPTS_HAVE_LITERAL(optionsp))
+ flags |= (optionsp->literal ? CM_PARSE_FLAG_LITERAL : 0);
+
+ if (CM_IOCTL_QOPTS_HAVE_FID(optionsp)) {
+ cm_fid_t fid;
+ cm_SkipIoctlPath(&ioctlp->ioctl);
+ cm_SetFid(&fid, optionsp->fid.cell, optionsp->fid.volume,
+ optionsp->fid.vnode, optionsp->fid.unique);
+ code = cm_GetSCache(&fid, &scp, userp, &req);
+ } else {
+ code = smb_ParseIoctlPath(ioctlp, userp, &req, &scp, flags);
+ }
+ if (code)
+ return code;
+
+ cm_IoctlSkipQueryOptions(&ioctlp->ioctl, userp);
+ }
+
+ code = cm_IoctlSetOwner(&ioctlp->ioctl, userp, scp, &req);
+
+ cm_ReleaseSCache(scp);
+
+ return code;
+}
+
+/*
+ * VIOC_SETGROUP
+ *
+ * This pioctl requires the use of the cm_ioctlQueryOptions_t structure.
+ *
+ */
+afs_int32
+smb_IoctlSetGroup(struct smb_ioctl *ioctlp, struct cm_user *userp, afs_uint32 pflags)
+{
+ afs_int32 code;
+ cm_scache_t *scp;
+ cm_req_t req;
+ cm_ioctlQueryOptions_t *optionsp;
+ afs_uint32 flags = 0;
+
+ smb_InitReq(&req);
+
+ optionsp = cm_IoctlGetQueryOptions(&ioctlp->ioctl, userp);
+ if (optionsp) {
+ if (CM_IOCTL_QOPTS_HAVE_LITERAL(optionsp))
+ flags |= (optionsp->literal ? CM_PARSE_FLAG_LITERAL : 0);
+
+ if (CM_IOCTL_QOPTS_HAVE_FID(optionsp)) {
+ cm_fid_t fid;
+ cm_SkipIoctlPath(&ioctlp->ioctl);
+ cm_SetFid(&fid, optionsp->fid.cell, optionsp->fid.volume,
+ optionsp->fid.vnode, optionsp->fid.unique);
+ code = cm_GetSCache(&fid, &scp, userp, &req);
+ } else {
+ code = smb_ParseIoctlPath(ioctlp, userp, &req, &scp, flags);
+ }
+ if (code)
+ return code;
+
+ cm_IoctlSkipQueryOptions(&ioctlp->ioctl, userp);
+ }
+
+ code = cm_IoctlSetGroup(&ioctlp->ioctl, userp, scp, &req);
+
+ cm_ReleaseSCache(scp);
+
+ return code;
+}
+
+
+afs_int32
+smb_IoctlGetUnixMode(struct smb_ioctl *ioctlp, struct cm_user *userp, afs_uint32 pflags)
+{
+ afs_int32 code;
+ cm_scache_t *scp;
+ cm_req_t req;
+ cm_ioctlQueryOptions_t *optionsp;
+ afs_uint32 flags = 0;
+
+ smb_InitReq(&req);
+
+ optionsp = cm_IoctlGetQueryOptions(&ioctlp->ioctl, userp);
+ if (optionsp && CM_IOCTL_QOPTS_HAVE_LITERAL(optionsp))
+ flags |= (optionsp->literal ? CM_PARSE_FLAG_LITERAL : 0);
+
+ if (optionsp && CM_IOCTL_QOPTS_HAVE_FID(optionsp)) {
+ cm_fid_t fid;
+ cm_SkipIoctlPath(&ioctlp->ioctl);
+ cm_SetFid(&fid, optionsp->fid.cell, optionsp->fid.volume,
+ optionsp->fid.vnode, optionsp->fid.unique);
+ code = cm_GetSCache(&fid, &scp, userp, &req);
+ } else {
+ code = smb_ParseIoctlPath(ioctlp, userp, &req, &scp, flags);
+ }
+ if (code)
+ return code;
+
+ code = cm_IoctlGetUnixMode(&ioctlp->ioctl, userp, scp, &req);
+
+ cm_ReleaseSCache(scp);
+
+ return code;
+}
+
+
+/*
+ * VIOC_SETUNIXMODE
+ *
+ * This pioctl requires the use of the cm_ioctlQueryOptions_t structure.
+ */
+afs_int32
+smb_IoctlSetUnixMode(struct smb_ioctl *ioctlp, struct cm_user *userp, afs_uint32 pflags)
+{
+ afs_int32 code;
+ cm_scache_t *scp;
+ cm_req_t req;
+ cm_ioctlQueryOptions_t *optionsp;
+ afs_uint32 flags = 0;
+
+ smb_InitReq(&req);
+
+ optionsp = cm_IoctlGetQueryOptions(&ioctlp->ioctl, userp);
+ if (optionsp) {
+ if (CM_IOCTL_QOPTS_HAVE_LITERAL(optionsp))
+ flags |= (optionsp->literal ? CM_PARSE_FLAG_LITERAL : 0);
+
+ if (CM_IOCTL_QOPTS_HAVE_FID(optionsp)) {
+ cm_fid_t fid;
+ cm_SkipIoctlPath(&ioctlp->ioctl);
+ cm_SetFid(&fid, optionsp->fid.cell, optionsp->fid.volume,
+ optionsp->fid.vnode, optionsp->fid.unique);
+ code = cm_GetSCache(&fid, &scp, userp, &req);
+ } else {
+ code = smb_ParseIoctlPath(ioctlp, userp, &req, &scp, flags);
+ }
+ if (code)
+ return code;
+
+ cm_IoctlSkipQueryOptions(&ioctlp->ioctl, userp);
+ }
+
+ code = cm_IoctlSetUnixMode(&ioctlp->ioctl, userp, scp, &req);
+
+ cm_ReleaseSCache(scp);
+
+ return code;
+}
+