From: Jeffrey Altman Date: Wed, 1 Jul 2009 21:25:28 +0000 (+0000) Subject: windows-fs-chown-chgrp-20090701 X-Git-Tag: openafs-devel-1_5_61~188 X-Git-Url: https://git.michaelhowe.org/gitweb/?a=commitdiff_plain;h=ffd065a69578ad26c860b0b3e54053d6432c4a21;p=packages%2Fo%2Fopenafs.git windows-fs-chown-chgrp-20090701 LICENSE MIT On Windows there is no chown or chgrp command that can be used to change the owner or group of an object in AFS. Therefore we add them to the fs command. Usage: fs chown -owner [-path +] [-literal] [-help] Where: -literal literal evaluation of mountpoints and symlinks Usage: fs chgrp -group [-path +] [-literal] [-help] Where: -literal literal evaluation of mountpoints and symlinks --- diff --git a/src/WINNT/afsd/cm_ioctl.c b/src/WINNT/afsd/cm_ioctl.c index bf3c9f44d..251107b5d 100644 --- a/src/WINNT/afsd/cm_ioctl.c +++ b/src/WINNT/afsd/cm_ioctl.c @@ -882,6 +882,84 @@ cm_IoctlGetOwner(struct cm_ioctl *ioctlp, struct cm_user *userp, cm_scache_t *sc } +/* + * VIOC_SETOWNER 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_IoctlSetOwner(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 owner; + cm_attr_t attr; + + memset(&attr, 0, sizeof(attr)); + + cp = ioctlp->inDatap; + memcpy((char *)&owner, cp, sizeof(afs_uint32)); + + attr.mask = CM_ATTRMASK_OWNER; + attr.owner = owner; + + code = cm_SetAttr(scp, &attr, userp, reqp); + } + return code; +} + + +/* + * VIOC_SETGROUP internals. + * + * Assumes that pioctl path has been parsed or skipped + * and that cm_ioctlQueryOptions_t have been parsed and skipped. + * + */ +afs_int32 +cm_IoctlSetGroup(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 group; + cm_attr_t attr; + + memset(&attr, 0, sizeof(attr)); + + cp = ioctlp->inDatap; + memcpy((char *)&group, cp, sizeof(afs_uint32)); + + attr.mask = CM_ATTRMASK_GROUP; + attr.group = group; + + code = cm_SetAttr(scp, &attr, userp, reqp); + } + return code; +} + + /* * VIOCWHEREIS internals. * @@ -1732,9 +1810,9 @@ cm_IoctlGetSPrefs(struct cm_ioctl *ioctlp, struct cm_user *userp) continue; /* catch up to where we left off */ } - if ( vlonly && (tsp->type == CM_SERVER_FILE) ) + if ( vlonly && (tsp->type != CM_SERVER_VLDB) ) continue; /* ignore fileserver for -vlserver option*/ - if ( !vlonly && (tsp->type == CM_SERVER_VLDB) ) + if ( !vlonly && (tsp->type != CM_SERVER_FILE) ) continue; /* ignore vlservers */ srvout->host = tsp->addr.sin_addr; diff --git a/src/WINNT/afsd/cm_ioctl.h b/src/WINNT/afsd/cm_ioctl.h index 66c7cc2e7..d0827f3ca 100644 --- a/src/WINNT/afsd/cm_ioctl.h +++ b/src/WINNT/afsd/cm_ioctl.h @@ -176,6 +176,10 @@ extern afs_int32 cm_IoctlGetFid(cm_ioctl_t *ioctlp, cm_user_t *userp, cm_scache_ extern afs_int32 cm_IoctlGetOwner(cm_ioctl_t *ioctlp, cm_user_t *userp, cm_scache_t *scp, cm_req_t *reqp); +extern afs_int32 cm_IoctlSetOwner(cm_ioctl_t *ioctlp, cm_user_t *userp, cm_scache_t *scp, cm_req_t *reqp); + +extern afs_int32 cm_IoctlSetGroup(cm_ioctl_t *ioctlp, cm_user_t *userp, cm_scache_t *scp, cm_req_t *reqp); + extern afs_int32 cm_IoctlWhereIs(cm_ioctl_t *ioctlp, cm_user_t *userp, cm_scache_t *scp, cm_req_t *reqp); extern afs_int32 cm_IoctlStatMountPoint(cm_ioctl_t *ioctlp, cm_user_t *userp, cm_scache_t *scp, cm_req_t *reqp); diff --git a/src/WINNT/afsd/fs.c b/src/WINNT/afsd/fs.c index 5ebadde47..547234c1f 100644 --- a/src/WINNT/afsd/fs.c +++ b/src/WINNT/afsd/fs.c @@ -1653,6 +1653,7 @@ ExamineCmd(struct cmd_syndesc *as, void *arock) blob.out = (char *) &owner; if (0 == pioctl_utf8(ti->data, VIOCGETOWNER, &blob, 1)) { char oname[PR_MAXNAMELEN] = "(unknown)"; + char gname[PR_MAXNAMELEN] = "(unknown)"; char confDir[257]; /* Go to the PRDB and see if this all number username is valid */ @@ -1660,7 +1661,8 @@ ExamineCmd(struct cmd_syndesc *as, void *arock) pr_Initialize(1, confDir, cell); pr_SIdToName(owner[0], oname); - printf("Owner %s (%u) Group %u\n", oname, owner[0], owner[1]); + pr_SIdToName(owner[1], gname); + printf("Owner %s (%u) Group %s (%u)\n", oname, owner[0], gname, owner[1]); } blob.out = space; @@ -3802,7 +3804,6 @@ GetFidCmd(struct cmd_syndesc *as, void *arock) for(ti=as->parms[0].items; ti; ti=ti->next) { cm_fid_t fid; afs_uint32 filetype; - afs_uint32 owner[2]; char cell[CELL_MAXNAMELEN]; /* once per file */ @@ -4711,6 +4712,188 @@ TestVolStatCmd(struct cmd_syndesc *as, void *arock) return 0; } +static int +ChOwnCmd(struct cmd_syndesc *as, void *arock) +{ + afs_int32 code; + struct ViceIoctl blob; + struct cmd_item *ti; + int error = 0; + int literal = 0; + struct { + cm_ioctlQueryOptions_t options; + afs_uint32 owner; + } inData; + afs_uint32 ownerId; + char * ownerStr; + char confDir[257]; + + cm_GetConfigDir(confDir, sizeof(confDir)); + + if (as->parms[2].items) + literal = 1; + + ownerStr = as->parms[0].items->data; + ownerId = atoi(ownerStr); + + SetDotDefault(&as->parms[1].items); + for(ti=as->parms[1].items; ti; ti=ti->next) { + cm_fid_t fid; + afs_uint32 filetype; + char cell[CELL_MAXNAMELEN]; + + /* once per file */ + memset(&fid, 0, sizeof(fid)); + memset(&inData, 0, sizeof(inData)); + filetype = 0; + inData.options.size = sizeof(inData.options); + inData.options.field_flags |= CM_IOCTL_QOPTS_FIELD_LITERAL; + inData.options.literal = literal; + blob.in_size = inData.options.size; /* no variable length data */ + blob.in = &inData; + + blob.out_size = sizeof(cm_fid_t); + blob.out = (char *) &fid; + if (0 == pioctl_utf8(ti->data, VIOCGETFID, &blob, 1)) { + inData.options.field_flags |= CM_IOCTL_QOPTS_FIELD_FID; + inData.options.fid = fid; + } else { + Die(errno, ti->data); + error = 1; + continue; + } + + /* + * if the owner was specified as a numeric value, + * then we can just use it. Otherwise, we need + * to know the cell of the path to determine which + * ptserver to contact in order to convert the name + * to a numeric value. + */ + if (ownerId == 0) { + blob.out_size = CELL_MAXNAMELEN; + blob.out = cell; + + code = pioctl_utf8(ti->data, VIOC_FILE_CELL_NAME, &blob, 1); + /* + * We now know the cell for the target and we need to + * convert the ownerStr to the Id for this user + */ + pr_Initialize(1, confDir, cell); + code = pr_SNameToId(ownerStr, &inData.owner); + pr_End(); + + if (code || inData.owner == ANONYMOUSID ) { + Die(ECHILD, ti->data); + error = 1; + continue; + } + } else { + inData.owner = ownerId; + } + + blob.in_size = sizeof(inData); + blob.out = NULL; + blob.out_size = 0; + code = pioctl_utf8(ti->data, VIOC_SETOWNER, &blob, 1); + if (code) { + Die(errno, ti->data); + } + } + return error; +} + +static int +ChGrpCmd(struct cmd_syndesc *as, void *arock) +{ + afs_int32 code; + struct ViceIoctl blob; + struct cmd_item *ti; + int error = 0; + int literal = 0; + struct { + cm_ioctlQueryOptions_t options; + afs_uint32 group; + } inData; + afs_uint32 groupId; + char * groupStr; + char confDir[257]; + + cm_GetConfigDir(confDir, sizeof(confDir)); + + if (as->parms[2].items) + literal = 1; + + groupStr = as->parms[0].items->data; + groupId = atoi(groupStr); + + SetDotDefault(&as->parms[1].items); + for(ti=as->parms[1].items; ti; ti=ti->next) { + cm_fid_t fid; + afs_uint32 filetype; + char cell[CELL_MAXNAMELEN]; + + /* once per file */ + memset(&fid, 0, sizeof(fid)); + memset(&inData, 0, sizeof(inData)); + filetype = 0; + inData.options.size = sizeof(inData.options); + inData.options.field_flags |= CM_IOCTL_QOPTS_FIELD_LITERAL; + inData.options.literal = literal; + blob.in_size = inData.options.size; /* no variable length data */ + blob.in = &inData; + + blob.out_size = sizeof(cm_fid_t); + blob.out = (char *) &fid; + if (0 == pioctl_utf8(ti->data, VIOCGETFID, &blob, 1)) { + inData.options.field_flags |= CM_IOCTL_QOPTS_FIELD_FID; + inData.options.fid = fid; + } else { + Die(errno, ti->data); + error = 1; + continue; + } + + /* + * if the group was specified as a numeric value, + * then we can just use it. Otherwise, we need + * to know the cell of the path to determine which + * ptserver to contact in order to convert the name + * to a numeric value. + */ + if (groupId == 0) { + blob.out_size = CELL_MAXNAMELEN; + blob.out = cell; + + code = pioctl_utf8(ti->data, VIOC_FILE_CELL_NAME, &blob, 1); + /* + * We now know the cell for the target and we need to + * convert the groupStr to the Id for this user + */ + pr_Initialize(1, confDir, cell); + code = pr_SNameToId(groupStr, &inData.group); + pr_End(); + + if (code || inData.group == ANONYMOUSID ) { + Die(ECHILD, ti->data); + error = 1; + continue; + } + } else { + inData.group = groupId; + } + + blob.in_size = sizeof(inData); + blob.out = NULL; + blob.out_size = 0; + code = pioctl_utf8(ti->data, VIOC_SETGROUP, &blob, 1); + if (code) { + Die(errno, ti->data); + } + } + return error; +} + #ifndef WIN32 #include "AFS_component_version_number.c" #endif @@ -5071,6 +5254,16 @@ int wmain(int argc, wchar_t **wargv) cmd_AddParm(ts, "-path", CMD_LIST, CMD_OPTIONAL, "dir/file path"); cmd_AddParm(ts, "-literal", CMD_FLAG, CMD_OPTIONAL, "literal evaluation of mountpoints and symlinks"); + ts = cmd_CreateSyntax("chown", ChOwnCmd, NULL, "set owner for object(s) in afs"); + cmd_AddParm(ts, "-owner", CMD_SINGLE, 0, "user name or id"); + cmd_AddParm(ts, "-path", CMD_LIST, CMD_OPTIONAL, "dir/file path"); + cmd_AddParm(ts, "-literal", CMD_FLAG, CMD_OPTIONAL, "literal evaluation of mountpoints and symlinks"); + + ts = cmd_CreateSyntax("chgrp", ChGrpCmd, NULL, "set owner for object(s) in afs"); + cmd_AddParm(ts, "-group", CMD_SINGLE, 0, "user/group name or id"); + cmd_AddParm(ts, "-path", CMD_LIST, CMD_OPTIONAL, "dir/file path"); + cmd_AddParm(ts, "-literal", CMD_FLAG, CMD_OPTIONAL, "literal evaluation of mountpoints and symlinks"); + code = cmd_Dispatch(argc, argv); if (rxInitDone) @@ -5141,6 +5334,12 @@ Die(int code, char *filename) else fprintf(stderr,"%s: All servers are down\n", pn); } + else if (code == ECHILD) { /* hack */ + if (filename) + fprintf(stderr,"%s: Invalid owner specified for '%s'\n", pn, filename); + else + fprintf(stderr,"%s: Invalid owner specified\n", pn); + } else { if (filename) fprintf(stderr,"%s:'%s'", pn, filename); diff --git a/src/WINNT/afsd/smb_iocons.h b/src/WINNT/afsd/smb_iocons.h index f44d8a2ae..d0601977a 100644 --- a/src/WINNT/afsd/smb_iocons.h +++ b/src/WINNT/afsd/smb_iocons.h @@ -95,6 +95,8 @@ struct sbstruct { #define VIOC_PATH_AVAILABILITY 0x31 #define VIOC_GETFILETYPE 0x32 #define VIOC_UNICODECTL 0x33 +#define VIOC_SETOWNER 0x34 +#define VIOC_SETGROUP 0x35 #define VIOC_VOLSTAT_TEST 0x3F diff --git a/src/WINNT/afsd/smb_ioctl.c b/src/WINNT/afsd/smb_ioctl.c index 87be3219a..c2c339af4 100644 --- a/src/WINNT/afsd/smb_ioctl.c +++ b/src/WINNT/afsd/smb_ioctl.c @@ -87,6 +87,8 @@ smb_InitIoctl(void) 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; } /* called to make a fid structure into an IOCTL fid structure */ @@ -1102,6 +1104,7 @@ smb_IoctlGetACL(smb_ioctl_t *ioctlp, cm_user_t *userp) } else { code = smb_ParseIoctlPath(ioctlp, userp, &req, &scp, flags); } + if (code) return code; @@ -1825,3 +1828,94 @@ smb_IoctlVolStatTest(struct smb_ioctl *ioctlp, struct cm_user *userp) 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_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_GETOWNER + * + * This pioctl requires the use of the cm_ioctlQueryOptions_t structure. + * + */ +afs_int32 +smb_IoctlSetGroup(struct smb_ioctl *ioctlp, struct cm_user *userp) +{ + 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; +} + + + diff --git a/src/WINNT/afsd/smb_ioctl.h b/src/WINNT/afsd/smb_ioctl.h index 202f5dcf7..033533f60 100644 --- a/src/WINNT/afsd/smb_ioctl.h +++ b/src/WINNT/afsd/smb_ioctl.h @@ -200,4 +200,8 @@ extern afs_int32 smb_IoctlVolStatTest(struct smb_ioctl *ioctlp, struct cm_user * extern afs_int32 smb_IoctlUnicodeControl(struct smb_ioctl *ioctlp, struct cm_user * userp); +extern afs_int32 smb_IoctlSetOwner(struct smb_ioctl *ioctlp, struct cm_user *userp); + +extern afs_int32 smb_IoctlSetGroup(struct smb_ioctl *ioctlp, struct cm_user *userp); + #endif /* __SMB_IOCTL_H_ENV__ */