1331 slashp = strchr(bpath, '/');
1332
1333 /* if no '/', just return the pool name */
1334 if (slashp == NULL) {
1335 return (0);
1336 }
1337
1338 /* if not a number, just return the root dataset name */
1339 if (str_to_uint64(slashp+1, &objnum)) {
1340 return (0);
1341 }
1342
1343 *slashp = '\0';
1344 error = dsl_dsobj_to_dsname(bpath, objnum, outpath);
1345 *slashp = '/';
1346
1347 return (error);
1348 }
1349
1350 /*
1351 * zfs_check_global_label:
1352 * Check that the hex label string is appropriate for the dataset
1353 * being mounted into the global_zone proper.
1354 *
1355 * Return an error if the hex label string is not default or
1356 * admin_low/admin_high. For admin_low labels, the corresponding
1357 * dataset must be readonly.
1358 */
1359 int
1360 zfs_check_global_label(const char *dsname, const char *hexsl)
1361 {
1362 if (strcasecmp(hexsl, ZFS_MLSLABEL_DEFAULT) == 0)
1363 return (0);
1364 if (strcasecmp(hexsl, ADMIN_HIGH) == 0)
1365 return (0);
1366 if (strcasecmp(hexsl, ADMIN_LOW) == 0) {
1367 /* must be readonly */
1368 uint64_t rdonly;
1369
1370 if (dsl_prop_get_integer(dsname,
1371 zfs_prop_to_name(ZFS_PROP_READONLY), &rdonly, NULL))
1372 return (SET_ERROR(EACCES));
1373 return (rdonly ? 0 : EACCES);
1374 }
1375 return (SET_ERROR(EACCES));
1376 }
1377
1378 /*
1379 * zfs_mount_label_policy:
1380 * Determine whether the mount is allowed according to MAC check.
1381 * by comparing (where appropriate) label of the dataset against
1382 * the label of the zone being mounted into. If the dataset has
1383 * no label, create one.
1384 *
1385 * Returns:
1386 * 0 : access allowed
1387 * >0 : error code, such as EACCES
1388 */
1389 static int
1390 zfs_mount_label_policy(vfs_t *vfsp, char *osname)
1391 {
1392 int error, retv;
1393 zone_t *mntzone = NULL;
1394 ts_label_t *mnt_tsl;
1395 bslabel_t *mnt_sl;
1396 bslabel_t ds_sl;
1397 char ds_hexsl[MAXNAMELEN];
1398
1399 retv = EACCES; /* assume the worst */
1400
1401 /*
1402 * Start by getting the dataset label if it exists.
1403 */
1404 error = dsl_prop_get(osname, zfs_prop_to_name(ZFS_PROP_MLSLABEL),
1405 1, sizeof (ds_hexsl), &ds_hexsl, NULL);
1406 if (error)
1407 return (SET_ERROR(EACCES));
|
1331 slashp = strchr(bpath, '/');
1332
1333 /* if no '/', just return the pool name */
1334 if (slashp == NULL) {
1335 return (0);
1336 }
1337
1338 /* if not a number, just return the root dataset name */
1339 if (str_to_uint64(slashp+1, &objnum)) {
1340 return (0);
1341 }
1342
1343 *slashp = '\0';
1344 error = dsl_dsobj_to_dsname(bpath, objnum, outpath);
1345 *slashp = '/';
1346
1347 return (error);
1348 }
1349
1350 /*
1351 * Check that the hex label string is appropriate for the dataset being
1352 * mounted into the global_zone proper.
1353 *
1354 * Return an error if the hex label string is not default or
1355 * admin_low/admin_high. For admin_low labels, the corresponding
1356 * dataset must be readonly.
1357 */
1358 int
1359 zfs_check_global_label(const char *dsname, const char *hexsl)
1360 {
1361 if (strcasecmp(hexsl, ZFS_MLSLABEL_DEFAULT) == 0)
1362 return (0);
1363 if (strcasecmp(hexsl, ADMIN_HIGH) == 0)
1364 return (0);
1365 if (strcasecmp(hexsl, ADMIN_LOW) == 0) {
1366 /* must be readonly */
1367 uint64_t rdonly;
1368
1369 if (dsl_prop_get_integer(dsname,
1370 zfs_prop_to_name(ZFS_PROP_READONLY), &rdonly, NULL))
1371 return (SET_ERROR(EACCES));
1372 return (rdonly ? 0 : EACCES);
1373 }
1374 return (SET_ERROR(EACCES));
1375 }
1376
1377 /*
1378 * Determine whether the mount is allowed according to MAC check.
1379 * by comparing (where appropriate) label of the dataset against
1380 * the label of the zone being mounted into. If the dataset has
1381 * no label, create one.
1382 *
1383 * Returns 0 if access allowed, error otherwise (e.g. EACCES)
1384 */
1385 static int
1386 zfs_mount_label_policy(vfs_t *vfsp, char *osname)
1387 {
1388 int error, retv;
1389 zone_t *mntzone = NULL;
1390 ts_label_t *mnt_tsl;
1391 bslabel_t *mnt_sl;
1392 bslabel_t ds_sl;
1393 char ds_hexsl[MAXNAMELEN];
1394
1395 retv = EACCES; /* assume the worst */
1396
1397 /*
1398 * Start by getting the dataset label if it exists.
1399 */
1400 error = dsl_prop_get(osname, zfs_prop_to_name(ZFS_PROP_MLSLABEL),
1401 1, sizeof (ds_hexsl), &ds_hexsl, NULL);
1402 if (error)
1403 return (SET_ERROR(EACCES));
|