18c2aff776a775d34a4c9893a4c72e0434d68e36artem/***************************************************************************
18c2aff776a775d34a4c9893a4c72e0434d68e36artem * CVSID: $Id: hal-storage-mount.c,v 1.7 2006/06/21 00:44:03 david Exp $
18c2aff776a775d34a4c9893a4c72e0434d68e36artem * hal-storage-mount.c : Mount wrapper
18c2aff776a775d34a4c9893a4c72e0434d68e36artem * Copyright (C) 2006 David Zeuthen, <david@fubar.dk>
18c2aff776a775d34a4c9893a4c72e0434d68e36artem * This program is free software; you can redistribute it and/or modify
18c2aff776a775d34a4c9893a4c72e0434d68e36artem * it under the terms of the GNU General Public License as published by
18c2aff776a775d34a4c9893a4c72e0434d68e36artem * the Free Software Foundation; either version 2 of the License, or
18c2aff776a775d34a4c9893a4c72e0434d68e36artem * (at your option) any later version.
18c2aff776a775d34a4c9893a4c72e0434d68e36artem * This program is distributed in the hope that it will be useful,
18c2aff776a775d34a4c9893a4c72e0434d68e36artem * but WITHOUT ANY WARRANTY; without even the implied warranty of
18c2aff776a775d34a4c9893a4c72e0434d68e36artem * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
18c2aff776a775d34a4c9893a4c72e0434d68e36artem * GNU General Public License for more details.
18c2aff776a775d34a4c9893a4c72e0434d68e36artem * You should have received a copy of the GNU General Public License
18c2aff776a775d34a4c9893a4c72e0434d68e36artem * along with this program; if not, write to the Free Software
18c2aff776a775d34a4c9893a4c72e0434d68e36artem * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
18c2aff776a775d34a4c9893a4c72e0434d68e36artem **************************************************************************/
18c2aff776a775d34a4c9893a4c72e0434d68e36artem mtab->n_mounts = getmntinfo (&mtab->mounts, MNT_NOWAIT);
18c2aff776a775d34a4c9893a4c72e0434d68e36artem#error TODO: set *mount_point to g_strdup()-ed value if mount_point!=NULL
18c2aff776a775d34a4c9893a4c72e0434d68e36artem /* TODO: fill out mount_point */
18c2aff776a775d34a4c9893a4c72e0434d68e36artem static struct vfstab v;
18c2aff776a775d34a4c9893a4c72e0434d68e36artem return getvfsent (handle, &v) == 0 ? v.vfs_special : NULL;
18c2aff776a775d34a4c9893a4c72e0434d68e36artem fprintf (stderr, "org.freedesktop.Hal.Device.Volume.UnknownFailure\n");
18c2aff776a775d34a4c9893a4c72e0434d68e36artem fprintf (stderr, "org.freedesktop.Hal.Device.Volume.Busy\n");
18c2aff776a775d34a4c9893a4c72e0434d68e36artem fprintf (stderr, "org.freedesktop.Hal.Device.Volume.NotMounted\n");
18c2aff776a775d34a4c9893a4c72e0434d68e36artem fprintf (stderr, "org.freedesktop.Hal.Device.Volume.NotMountedByHal\n");
18c2aff776a775d34a4c9893a4c72e0434d68e36artempermission_denied_privilege (const char *privilege, const char *uid)
18c2aff776a775d34a4c9893a4c72e0434d68e36artem fprintf (stderr, "org.freedesktop.Hal.Device.PermissionDeniedByPolicy\n");
18c2aff776a775d34a4c9893a4c72e0434d68e36artem fprintf (stderr, "%s refused uid %s\n", privilege, uid);
18c2aff776a775d34a4c9893a4c72e0434d68e36artem fprintf (stderr, "org.freedesktop.Hal.Device.Volume.PermissionDenied\n");
18c2aff776a775d34a4c9893a4c72e0434d68e36artem fprintf (stderr, "Device has %s volume.ignore set to TRUE. Refusing to mount.\n", device);
18c2aff776a775d34a4c9893a4c72e0434d68e36artem const char *udi,
18c2aff776a775d34a4c9893a4c72e0434d68e36artem LibHalVolume *volume, LibHalDrive *drive, const char *device,
18c2aff776a775d34a4c9893a4c72e0434d68e36artem const char *invoked_by_uid, const char *invoked_by_syscon_name,
18c2aff776a775d34a4c9893a4c72e0434d68e36artem printf ("invoked by system bus connection = %s\n", invoked_by_syscon_name);
18c2aff776a775d34a4c9893a4c72e0434d68e36artem if (libhal_device_get_property_bool (hal_ctx, udi, "volume.ignore", &error) ||
18c2aff776a775d34a4c9893a4c72e0434d68e36artem * When device allocation is enabled (bsmconv or TX), we
18c2aff776a775d34a4c9893a4c72e0434d68e36artem * set volume.ignore on all volumes, but still want
18c2aff776a775d34a4c9893a4c72e0434d68e36artem * Mount() to succeed when called from the euid=0
18c2aff776a775d34a4c9893a4c72e0434d68e36artem * device allocation program.
18c2aff776a775d34a4c9893a4c72e0434d68e36artem not_mounted ("According to HAL, the volume is not mounted");
18c2aff776a775d34a4c9893a4c72e0434d68e36artem /* check hal's mtab file to verify the device to unmount is actually mounted by hal */
18c2aff776a775d34a4c9893a4c72e0434d68e36artem unknown_error ("Cannot seek to end of /media/.hal-mtab");
18c2aff776a775d34a4c9893a4c72e0434d68e36artem unknown_error ("Cannot determine size of /media/.hal-mtab");
18c2aff776a775d34a4c9893a4c72e0434d68e36artem num_read = fread (hal_mtab_buf, 1, hal_mtab_orig_len, hal_mtab_orig);
18c2aff776a775d34a4c9893a4c72e0434d68e36artem /* find the entry we're going to unmount */
18c2aff776a775d34a4c9893a4c72e0434d68e36artem * Owner is allowed to take over. Before we have real
18c2aff776a775d34a4c9893a4c72e0434d68e36artem * ownership in HAL, assume it's the console owner.
18c2aff776a775d34a4c9893a4c72e0434d68e36artem#endif /* sun */
18c2aff776a775d34a4c9893a4c72e0434d68e36artem not_mounted_by_hal ("Device to unmount is not in /media/.hal-mtab so it is not mounted by HAL");
18c2aff776a775d34a4c9893a4c72e0434d68e36artem /* bail out, unless if we got the "hal-storage-can-unmount-volumes-mounted-by-others" privilege only
18c2aff776a775d34a4c9893a4c72e0434d68e36artem * if mounted_by_other_uid==TRUE
18c2aff776a775d34a4c9893a4c72e0434d68e36artem * We allow uid 0 to actually ensure that Unmount(options=["lazy"], "/dev/blah") works from addon-storage.
18c2aff776a775d34a4c9893a4c72e0434d68e36artem if ((strcmp (invoked_by_uid, "0") != 0) && mounted_by_other_uid) {
18c2aff776a775d34a4c9893a4c72e0434d68e36artem /* TODO: actually check for privilege "hal-storage-can-unmount-volumes-mounted-by-others" */
18c2aff776a775d34a4c9893a4c72e0434d68e36artem permission_denied_privilege ("hal-storage-can-unmount-volumes-mounted-by-others", invoked_by_uid);
18c2aff776a775d34a4c9893a4c72e0434d68e36artem /* create new .hal-mtab~ file without the entry we're going to unmount */
18c2aff776a775d34a4c9893a4c72e0434d68e36artem if (i > 0) {
18c2aff776a775d34a4c9893a4c72e0434d68e36artem if (fwrite (lines[i], 1, strlen (lines[i]), hal_mtab_new) != strlen (lines[i])) {
18c2aff776a775d34a4c9893a4c72e0434d68e36artem /* construct arguments to /bin/umount */
18c2aff776a775d34a4c9893a4c72e0434d68e36artem printf ("will umount %s (mounted at '%s'), mounted_by_other_uid=%d\n",
18c2aff776a775d34a4c9893a4c72e0434d68e36artem device, mount_point_to_unmount, mounted_by_other_uid);
18c2aff776a775d34a4c9893a4c72e0434d68e36artem /* invoke /bin/umount */
18c2aff776a775d34a4c9893a4c72e0434d68e36artem /* check if unmount was succesful */
18c2aff776a775d34a4c9893a4c72e0434d68e36artem printf ("%s error %d, stdout='%s', stderr='%s'\n", UMOUNT, exit_status, sout, serr);
18c2aff776a775d34a4c9893a4c72e0434d68e36artem audit_volume (adt_data, ADT_detach, WEXITSTATUS(exit_status),
18c2aff776a775d34a4c9893a4c72e0434d68e36artem "solaris.device.mount.removable",
18c2aff776a775d34a4c9893a4c72e0434d68e36artem /* unmount was succesful, remove directory we created in Mount() */
18c2aff776a775d34a4c9893a4c72e0434d68e36artem if (strncmp (mount_point_to_unmount, "/media/", 7) == 0)
18c2aff776a775d34a4c9893a4c72e0434d68e36artem /* set new .hal-mtab file */
18c2aff776a775d34a4c9893a4c72e0434d68e36artem if (rename ("/media/.hal-mtab~", "/media/.hal-mtab") != 0) {
18c2aff776a775d34a4c9893a4c72e0434d68e36artem unknown_error ("Cannot rename /media/.hal-mtab~ to /media/.hal-mtab");
18c2aff776a775d34a4c9893a4c72e0434d68e36artem syslog (LOG_INFO, "unmounted %s from '%s' on behalf of uid %s", device, mount_point_to_unmount, invoked_by_uid);
18c2aff776a775d34a4c9893a4c72e0434d68e36artem const char *udi,
18c2aff776a775d34a4c9893a4c72e0434d68e36artem const char *invoked_by_uid, const char *invoked_by_syscon_name,
18c2aff776a775d34a4c9893a4c72e0434d68e36artem /* TODO: should we require privileges here? */
18c2aff776a775d34a4c9893a4c72e0434d68e36artem printf ("invoked by system bus connection = %s\n", invoked_by_syscon_name);
18c2aff776a775d34a4c9893a4c72e0434d68e36artem /* construct arguments to EJECT (e.g. /usr/bin/eject) */
18c2aff776a775d34a4c9893a4c72e0434d68e36artem /* invoke eject command */
18c2aff776a775d34a4c9893a4c72e0434d68e36artem * Solaris eject returns 4 for manually ejectable media like floppy.
18c2aff776a775d34a4c9893a4c72e0434d68e36artem * Consider it success.
18c2aff776a775d34a4c9893a4c72e0434d68e36artem audit_volume (adt_data, ADT_remove, WEXITSTATUS(exit_status),
18c2aff776a775d34a4c9893a4c72e0434d68e36artem "solaris.device.mount.removable", NULL, device, NULL);
18c2aff776a775d34a4c9893a4c72e0434d68e36artem#endif /* sun */
18c2aff776a775d34a4c9893a4c72e0434d68e36artem /* check if eject was succesful */
18c2aff776a775d34a4c9893a4c72e0434d68e36artem printf ("%s error %d, stdout='%s', stderr='%s'\n", EJECT, exit_status, sout, serr);
18c2aff776a775d34a4c9893a4c72e0434d68e36artem /* eject was succesful... */
18c2aff776a775d34a4c9893a4c72e0434d68e36artem printf ("%d: XYA attempting to get lock on /media/.hal-mtab-lock\n", getpid ());
18c2aff776a775d34a4c9893a4c72e0434d68e36artem lock_mtab_fd = open ("/media/.hal-mtab-lock", O_CREAT | O_RDWR);
18c2aff776a775d34a4c9893a4c72e0434d68e36artem printf ("%d: XYA got lock on /media/.hal-mtab-lock\n", getpid ());
18c2aff776a775d34a4c9893a4c72e0434d68e36artem printf ("%d: XYA released lock on /media/.hal-mtab-lock\n", getpid ());
18c2aff776a775d34a4c9893a4c72e0434d68e36artem/* map PolicyKit privilege to RBAC authorization */
18c2aff776a775d34a4c9893a4c72e0434d68e36artem if (strcmp (privilege, "hal-storage-removable-mount") == 0) {
18c2aff776a775d34a4c9893a4c72e0434d68e36artem authname = g_strdup ("solaris.device.mount.removable");
18c2aff776a775d34a4c9893a4c72e0434d68e36artem } else if (strcmp (privilege, "hal-storage-removable-mount-all-options") == 0) {
18c2aff776a775d34a4c9893a4c72e0434d68e36artem authname = g_strdup ("solaris.device.mount.alloptions.removable");
18c2aff776a775d34a4c9893a4c72e0434d68e36artem } else if (strcmp (privilege, "hal-storage-fixed-mount") == 0) {
18c2aff776a775d34a4c9893a4c72e0434d68e36artem } else if (strcmp (privilege, "hal-storage-fixed-mount-all-options") == 0) {
18c2aff776a775d34a4c9893a4c72e0434d68e36artem authname = g_strdup ("solaris.device.mount.alloptions.fixed");
18c2aff776a775d34a4c9893a4c72e0434d68e36artem /* replace '-' with '.' */
18c2aff776a775d34a4c9893a4c72e0434d68e36artemaudit_volume(const adt_export_data_t *imported_state, au_event_t event_id,
18c2aff776a775d34a4c9893a4c72e0434d68e36artem int result, const char *auth_used, const char *mount_point,
18c2aff776a775d34a4c9893a4c72e0434d68e36artem if ((event = adt_alloc_event(ah, event_id)) == NULL) {
18c2aff776a775d34a4c9893a4c72e0434d68e36artem if (result == 0) {
18c2aff776a775d34a4c9893a4c72e0434d68e36artem if (adt_put_event(event, ADT_SUCCESS, ADT_SUCCESS) != 0) {
18c2aff776a775d34a4c9893a4c72e0434d68e36artem#endif /* sun */