Q: How do I use FSSetCatalogInfo to change the UID and GID of a file? A: Apple specifically chose to ignore the UID and GID values you supply to FSSetCatalogInfo so as to improve compatibility with existing source code. The code in most applications copies a file's metadata by calling FSGetCatalogInfo on the source then calling FSSetCatalogInfo on the destination. However, Mac OS X does not let a non-root program change the UID of a file. Thus, if FSSetCatalogInfo was implemented in the obvious way and you used the standard copy algorithm to copy a file that you did not own, your program would fail with a permissions error.
At this point in time there is no way to set a file's UID or GID using the Carbon File Manager. The recommended workaround is to use the BSD call chown , as shown in Listing 1.
Listing 1. A version of FSSetCatalogInfo that sets the UID and GID
| #include <CoreServices/CoreServices.h>
#include <sys/param.h>
#include <unistd.h>
static OSStatus FSSetCatalogInfoIDs(const FSRef *ref,
FSCatalogInfoBitmap whichInfo,
const FSCatalogInfo *catalogInfo)
// A version of FSSetCatalogInfo that actually tries
// to set the FUID and FGID if you supply the
// kFSCatInfoPermissions flag. This is the current
// recommended workaround for <rdar://problem/2631025>.
// You can supply a userID or groupID value of -1
// to indicate that you don't want to change the value.
{
OSStatus err;
const FSPermissionInfo * permInfo;
uid_t uid;
gid_t gid;
err = FSSetCatalogInfo(ref, whichInfo, catalogInfo);
if ( (err == noErr) && (whichInfo & kFSCatInfoPermissions) ) {
permInfo = (const FSPermissionInfo *) catalogInfo->permissions;
uid = (uid_t) permInfo->userID;
gid = (gid_t) permInfo->groupID;
if (uid != -1 || gid != -1 ) {
char filePath[MAXPATHLEN];
err = FSRefMakePath(ref, (UInt8 *) filePath, sizeof(filePath));
if (err == noErr) {
err = chown(filePath, uid, gid);
if (err == -1) {
err = errno;
}
}
}
}
return err;
}
|
IMPORTANT:
The above code does not give you any special privileges. If you attempt to perform some operation that is restricted (enter man 2 chown in Terminal for information about those restrictions), FSSetCatalogInfoIDs will fail with an error. For information about how to get additional privileges, see the Authorization Services documentation.
|
Note:
If you discovered this problem because you're writing your own code to copy file system objects, you might consider using the code from the DTS sample code FSCopyObjects instead.
|
[Mar 26, 2003]
|