KDFS-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 <user name or id> [-path <dir/file path>+] [-literal] [-help]
Where: -literal  literal evaluation of mountpoints and symlinks

Usage: fs chgrp -group <user/group name or id> [-path <dir/file path>+] [-literal] [-help]
Where: -literal  literal evaluation of mountpoints and symlinks


(cherry picked from commit ffd065a695)
This commit is contained in:
Jeffrey Altman 2009-07-01 21:26:18 +00:00
parent 50245c93b9
commit 725d6ad02a
6 changed files with 385 additions and 4 deletions

View File

@ -902,6 +902,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.
*
@ -1776,9 +1854,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;

View File

@ -177,6 +177,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);

View File

@ -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);

View File

@ -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

View File

@ -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;
}

View File

@ -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__ */