summaryrefslogtreecommitdiff
path: root/libtrivfs/io-restrict-auth.c
diff options
context:
space:
mode:
Diffstat (limited to 'libtrivfs/io-restrict-auth.c')
-rw-r--r--libtrivfs/io-restrict-auth.c30
1 files changed, 22 insertions, 8 deletions
diff --git a/libtrivfs/io-restrict-auth.c b/libtrivfs/io-restrict-auth.c
index 2ecb0808..256c05f1 100644
--- a/libtrivfs/io-restrict-auth.c
+++ b/libtrivfs/io-restrict-auth.c
@@ -43,8 +43,9 @@ trivfs_S_io_restrict_auth (struct trivfs_protid *cred,
uid_t *uids, u_int nuids,
uid_t *gids, u_int ngids)
{
- struct trivfs_protid *newcred;
int i;
+ error_t err = 0;
+ struct trivfs_protid *newcred;
uid_t *newuids, *newgids;
int newnuids, newngids;
@@ -82,14 +83,27 @@ trivfs_S_io_restrict_auth (struct trivfs_protid *cred,
newcred->nuids = newnuids;
newcred->hook = cred->hook;
- io_restrict_auth (cred->realnode, &newcred->realnode,
- newuids, newnuids, newgids, newngids);
-
- if (trivfs_protid_create_hook)
- (*trivfs_protid_create_hook) (newcred);
+ err = io_restrict_auth (cred->realnode, &newcred->realnode,
+ newuids, newnuids, newgids, newngids);
+ if (!err && trivfs_protid_create_hook)
+ {
+ err = (*trivfs_protid_create_hook) (newcred);
+ if (err)
+ mach_port_deallocate (mach_task_self (), newcred->realnode);
+ }
- *newport = ports_get_right (newcred);
- *newporttype = MACH_MSG_TYPE_MAKE_SEND;
+ if (err)
+ /* Signal that the user destroy hook shouldn't be called on NEWCRED. */
+ newcred->realnode = MACH_PORT_NULL;
+ else
+ {
+ *newport = ports_get_right (newcred);
+ *newporttype = MACH_MSG_TYPE_MAKE_SEND;
+ }
+
+ /* This will destroy NEWCRED if we got an error and didn't do the
+ ports_get_right above. */
ports_port_deref (newcred);
+
return 0;
}