From 27469e59b134efef6c908a1bfa8162d4bf9b8275 Mon Sep 17 00:00:00 2001 From: Jeffrey Altman Date: Sat, 18 Dec 2010 18:36:18 -0500 Subject: [PATCH] Windows: Add VIOC_GETUNIXMODE and VIOC_SETUNIXMODE Add pioctls to get and set the UNIX mode bits for an object in AFS. Change-Id: I220047d8be50b5db511e41004b8248859f479c0c Reviewed-on: http://gerrit.openafs.org/3545 Tested-by: BuildBot Reviewed-by: Jeffrey Altman Tested-by: Jeffrey Altman --- src/WINNT/afsd/cm_ioctl.c | 70 +++++++++++++++++++++++++++++++++++++++ src/WINNT/afsd/cm_ioctl.h | 4 +++ src/WINNT/afsd/smb_iocons.h | 2 ++ src/WINNT/afsd/smb_ioctl.c | 79 +++++++++++++++++++++++++++++++++++++++++++++ src/WINNT/afsd/smb_ioctl.h | 4 +++ 5 files changed, 159 insertions(+) diff --git a/src/WINNT/afsd/cm_ioctl.c b/src/WINNT/afsd/cm_ioctl.c index 6acd625..1624cbf 100644 --- a/src/WINNT/afsd/cm_ioctl.c +++ b/src/WINNT/afsd/cm_ioctl.c @@ -3417,3 +3417,73 @@ cm_IoctlVolStatTest(struct cm_ioctl *ioctlp, struct cm_user *userp, cm_req_t *re return code; } + +/* + * VIOC_GETUNIXMODE internals. + * + * Assumes that pioctl path has been parsed or skipped. + * scp is held but not locked. + */ +afs_int32 +cm_IoctlGetUnixMode(struct cm_ioctl *ioctlp, struct cm_user *userp, cm_scache_t *scp, cm_req_t *reqp) +{ + afs_int32 code = 0; + char *cp; + + lock_ObtainWrite(&scp->rw); + code = cm_SyncOp(scp, NULL, userp, reqp, 0, + CM_SCACHESYNC_NEEDCALLBACK | CM_SCACHESYNC_GETSTATUS); + if (code == 0) + cm_SyncOpDone(scp, NULL, CM_SCACHESYNC_NEEDCALLBACK | CM_SCACHESYNC_GETSTATUS); + lock_ReleaseWrite(&scp->rw); + + if (code == 0) { + /* Copy all this junk into msg->im_data, keeping track of the lengths. */ + cp = ioctlp->outDatap; + memcpy(cp, (char *)&scp->unixModeBits, sizeof(afs_uint32)); + cp += sizeof(afs_uint32); + + /* return new size */ + ioctlp->outDatap = cp; + } + return code; +} + + +/* + * VIOC_SETUNIXMODE internals. + * + * Assumes that pioctl path has been parsed or skipped + * and that cm_ioctlQueryOptions_t have been parsed and skipped. + * + * scp is held but not locked. + */ +afs_int32 +cm_IoctlSetUnixMode(struct cm_ioctl *ioctlp, struct cm_user *userp, cm_scache_t *scp, cm_req_t *reqp) +{ + afs_int32 code = 0; + char *cp; + + lock_ObtainWrite(&scp->rw); + code = cm_SyncOp(scp, NULL, userp, reqp, 0, + CM_SCACHESYNC_NEEDCALLBACK | CM_SCACHESYNC_GETSTATUS); + if (code == 0) + cm_SyncOpDone(scp, NULL, CM_SCACHESYNC_NEEDCALLBACK | CM_SCACHESYNC_GETSTATUS); + lock_ReleaseWrite(&scp->rw); + + if (code == 0) { + afs_uint32 unixModeBits; + cm_attr_t attr; + + memset(&attr, 0, sizeof(attr)); + + cp = ioctlp->inDatap; + memcpy((char *)&unixModeBits, cp, sizeof(afs_uint32)); + + attr.mask = CM_ATTRMASK_UNIXMODEBITS; + attr.unixModeBits = unixModeBits; + + code = cm_SetAttr(scp, &attr, userp, reqp); + } + return code; +} diff --git a/src/WINNT/afsd/cm_ioctl.h b/src/WINNT/afsd/cm_ioctl.h index c884982..c47ecbb 100644 --- a/src/WINNT/afsd/cm_ioctl.h +++ b/src/WINNT/afsd/cm_ioctl.h @@ -281,6 +281,10 @@ extern afs_int32 cm_IoctlUnicodeControl(struct cm_ioctl *ioctlp, struct cm_user extern void TranslateExtendedChars(char *str); +extern afs_int32 cm_IoctlGetUnixMode(cm_ioctl_t *ioctlp, cm_user_t *userp, cm_scache_t *scp, cm_req_t *reqp); + +extern afs_int32 cm_IoctlSetUnixMode(cm_ioctl_t *ioctlp, cm_user_t *userp, cm_scache_t *scp, cm_req_t *reqp); + #endif /* __CM_IOCTL_INTERFACES_ONLY__ */ #endif /* __CM_IOCTL_H_ENV__ */ diff --git a/src/WINNT/afsd/smb_iocons.h b/src/WINNT/afsd/smb_iocons.h index 4d32a41..2310853 100644 --- a/src/WINNT/afsd/smb_iocons.h +++ b/src/WINNT/afsd/smb_iocons.h @@ -99,6 +99,8 @@ struct sbstruct { #define VIOC_SETGROUP 0x35 #define VIOC_FS_CMD 0x36 #define VIOCNEWCELL2 0x37 +#define VIOC_GETUNIXMODE 0x38 +#define VIOC_SETUNIXMODE 0x39 #define VIOC_VOLSTAT_TEST 0x3F diff --git a/src/WINNT/afsd/smb_ioctl.c b/src/WINNT/afsd/smb_ioctl.c index 1e33b95..db9de8a 100644 --- a/src/WINNT/afsd/smb_ioctl.c +++ b/src/WINNT/afsd/smb_ioctl.c @@ -94,6 +94,8 @@ smb_InitIoctl(void) 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 */ @@ -2089,4 +2091,81 @@ smb_IoctlSetGroup(struct smb_ioctl *ioctlp, struct cm_user *userp, afs_uint32 pf } +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; +} diff --git a/src/WINNT/afsd/smb_ioctl.h b/src/WINNT/afsd/smb_ioctl.h index 1165df6..5f0c090 100644 --- a/src/WINNT/afsd/smb_ioctl.h +++ b/src/WINNT/afsd/smb_ioctl.h @@ -207,4 +207,8 @@ extern afs_int32 smb_IoctlSetOwner(struct smb_ioctl *ioctlp, struct cm_user *use extern afs_int32 smb_IoctlSetGroup(struct smb_ioctl *ioctlp, struct cm_user *userp, afs_uint32 flags); +extern afs_int32 smb_IoctlGetUnixMode(struct smb_ioctl *ioctlp, struct cm_user *userp, afs_uint32 flags); + +extern afs_int32 smb_IoctlSetUnixMode(struct smb_ioctl *ioctlp, struct cm_user *userp, afs_uint32 flags); + #endif /* __SMB_IOCTL_H_ENV__ */ -- 1.9.4