ArcCheck.pm revision 1.25
1155310Srwatson# ex:ts=8 sw=4:
2155310Srwatson# $OpenBSD: ArcCheck.pm,v 1.25 2014/04/22 18:22:20 espie Exp $
3155310Srwatson#
4156288Srwatson# Copyright (c) 2005-2006 Marc Espie <espie@openbsd.org>
5155310Srwatson#
6156288Srwatson# Permission to use, copy, modify, and distribute this software for any
7156288Srwatson# purpose with or without fee is hereby granted, provided that the above
8156288Srwatson# copyright notice and this permission notice appear in all copies.
9156288Srwatson#
10156288Srwatson# THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
11156288Srwatson# WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
12156288Srwatson# MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
13156288Srwatson# ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
14156288Srwatson# WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
15156310Srwatson# ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
16156288Srwatson# OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
17156288Srwatson
18156288Srwatson# Supplementary code to handle archives in the package context.
19156288Srwatson# Contrarily to GNU-tar, we do not change the archive format, but by
20156288Srwatson# convention,  the names LongName\d+ and LongLink\d correspond to names
21156288Srwatson# too long to fit. The actual names reside in the PLIST, but the archive
22156288Srwatson# is still a valid archive.
23156288Srwatson
24156288Srwatsonuse strict;
25156288Srwatsonuse warnings;
26161636Srwatson
27156288Srwatsonuse OpenBSD::Ustar;
28156288Srwatson
29156288Srwatsonpackage OpenBSD::Ustar::Object;
30161866Srwatson
31161866Srwatson# match archive header name against PackingElement item
32156288Srwatsonsub check_name
33161866Srwatson{
34161866Srwatson	my ($self, $item) = @_;
35161866Srwatson	return $self->name eq $item->name;
36161866Srwatson}
37161866Srwatson
38161866Srwatson# match archive header link name against actual link names
39161866Srwatsonsub check_linkname
40155310Srwatson{
41159984Srwatson	my ($self, $linkname) = @_;
42159984Srwatson	my $c = $self->{linkname};
43155310Srwatson	if ($self->isHardLink && defined $self->{cwd}) {
44159984Srwatson		$c = $self->{cwd}.'/'.$c;
45159984Srwatson	}
46155310Srwatson	return $c eq $linkname;
47156288Srwatson}
48156288Srwatson
49156288Srwatsonuse POSIX;
50161636Srwatson
51161636Srwatsonsub verify_modes
52161636Srwatson{
53161636Srwatson	my ($o, $item) = @_;
54161636Srwatson	my $result = 1;
55155310Srwatson
56155310Srwatson	if (!defined $item->{owner} && !$o->isSymLink) {
57	    if ($o->{uname} ne 'root' && $o->{uname} ne 'bin') {
58		    $o->errsay("Error: no \@owner for #1 (#2)",
59			$item->fullname, $o->{uname});
60	    		$result = 0;
61	    }
62	}
63	if (!defined $item->{group} && !$o->isSymLink) {
64	    if ($o->{gname} ne 'bin' && $o->{gname} ne 'wheel') {
65		if (($o->{mode} & (S_ISUID | S_ISGID | S_IWGRP)) != 0) {
66		    $o->errsay("Error: no \@group for #1 (#2), which has mode #3",
67			$item->fullname, $o->{uname},
68			sprintf("%4o", $o->{mode} & (S_IRWXU | S_IRWXG | S_IRWXO | S_ISUID | S_ISGID)));
69	    		$result = 0;
70		} else {
71		    $o->errsay("Warning: no \@group for #1 (#2)",
72			$item->fullname, $o->{gname});
73	    	}
74	    }
75	}
76	if (!defined $item->{mode} && $o->isFile) {
77	    if (($o->{mode} & (S_ISUID | S_ISGID | S_IWOTH)) != 0 ||
78	    	($o->{mode} & S_IROTH) == 0 || ($o->{mode} & S_IRGRP) == 0) {
79		    $o->errsay("Error: weird mode for #1: #2",
80			$item->fullname,
81			sprintf("%4o", $o->{mode} & (S_IRWXU | S_IRWXG | S_IRWXO | S_ISUID | S_ISGID)));
82	    		$result = 0;
83	    }
84	}
85	return $result;
86}
87
88package OpenBSD::Ustar;
89use POSIX;
90
91# prepare item and introduce long names where needed.
92sub prepare_long
93{
94	my ($self, $item) = @_;
95	my $entry;
96	if (defined $item->{wtempname}) {
97		$entry = $self->prepare($item->{wtempname}, '');
98	} else {
99		$entry = $self->prepare($item->name);
100	}
101	if (!defined $entry->{uname}) {
102		$self->fatal("No user name for #1 (uid #2)",
103		    $item->name, $entry->{uid});
104	}
105	if (!defined $entry->{gname}) {
106		$self->fatal("No group name for #1 (uid #2)",
107		    $item->name, $entry->{gid});
108	}
109	# if we're going to set the group or owner, sguid bits won't
110	# survive the extraction
111	if (defined $item->{group} || defined $item->{owner}) {
112		$entry->{mode} &= ~(S_ISUID|S_ISGID);
113	}
114	# likewise, we skip links on extractions, so hey, don't even care
115	# about modes and stuff.
116	if ($entry->isSymLink) {
117		$entry->{mode} = 0777;
118		$entry->{uid} = 0;
119		$entry->{gid} = 0;
120		$entry->{uname} = 'root';
121		$entry->{gname} = 'wheel';
122	}
123
124	$entry->set_name($item->name);
125	return $entry;
126}
127
1281;
129