mirror of
https://git.openafs.org/openafs.git
synced 2025-01-18 06:50:12 +00:00
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:
parent
50245c93b9
commit
725d6ad02a
@ -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;
|
||||
|
@ -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);
|
||||
|
@ -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);
|
||||
|
@ -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
|
||||
|
||||
|
@ -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;
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
@ -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__ */
|
||||
|
Loading…
Reference in New Issue
Block a user