~apparmor-dev/apparmor/2_3

« back to all changes in this revision

Viewing changes to management/yastui/src/agents/ag_complain

  • Committer: jrjohansen
  • Date: 2008-05-19 22:46:34 UTC
  • Revision ID: svn-v4:40609528-9d10-0410-9bd8-e926d5471da9:trunk:1247
move yastui to deprecated as the YaST ui is now being maintained and developed in the YaST svn

Show diffs side-by-side

added added

removed removed

Lines of Context:
1
 
#!/usr/bin/perl
2
 
# ------------------------------------------------------------------
3
 
#
4
 
#    Copyright (C) 2002-2005 Novell/SUSE
5
 
#
6
 
#    This program is free software; you can redistribute it and/or
7
 
#    modify it under the terms of version 2 of the GNU General Public
8
 
#    License published by the Free Software Foundation.
9
 
#
10
 
# ------------------------------------------------------------------
11
 
 
12
 
################################################################################
13
 
# ag_complain
14
 
#
15
 
#  - Generates list of profiles with complain/enforce info
16
 
#  - Toggles profiles between complain/enforce modes
17
 
#
18
 
#  Requires:
19
 
#        - /usr/lib/perl5/vendor_perl/Immunix/SubDomain.pm
20
 
#
21
 
#  Input (Optional):
22
 
#               - param 'showall' == 1 to change modes for profiles without associated 
23
 
#                 binaries (i.e. 'inactive' profiles), 'showall' effects all of the
24
 
#                 parameters listed below
25
 
#               - param 'all' to change modes for all active profiles
26
 
#       - profile names to change, for single profiles 
27
 
#       - nothing if listing just active profiles
28
 
#
29
 
#               - may allow multiple profiles in the future
30
 
#
31
 
################################################################################
32
 
 
33
 
use strict;
34
 
use Locale::gettext;
35
 
use POSIX;
36
 
use ycp;
37
 
 
38
 
use Immunix::SubDomain;
39
 
 
40
 
setlocale(LC_MESSAGES, "");
41
 
textdomain("yast2-apparmor");
42
 
 
43
 
our $UI_Mode = "yast-agent";
44
 
 
45
 
sub getProfPath ($) {
46
 
 
47
 
    my $profName = shift;
48
 
    my $profPath = undef;
49
 
 
50
 
    if ( ! -f "$profiledir/$profName" ) {
51
 
 
52
 
        ycp::y2milestone("Couldn't find file $profiledir/$profName.");
53
 
 
54
 
    } elsif (open PROF, "<$profiledir/$profName") {
55
 
 
56
 
        while(<PROF>) {
57
 
          if (/^\/\w+/) {
58
 
            $profPath = (split(/\s+[\{||flag]/, $_))[0];
59
 
            last;
60
 
          }
61
 
        }
62
 
 
63
 
    close PROF;
64
 
 
65
 
    } else {
66
 
        ycp::y2milestone("Couldn't open $profiledir/$profName for reading.");
67
 
      }
68
 
    return $profPath;
69
 
}
70
 
 
71
 
# checks for reasonable filename characteristics
72
 
sub badFileName {
73
 
 
74
 
    my $profName = shift;
75
 
    my $profPath = undef;
76
 
        my $allProfs = shift || 0;
77
 
    my $badFileName = 1;
78
 
 
79
 
    if ( $profName !~ /^\// ) {
80
 
                $profPath = getProfPath($profName);
81
 
    } else {
82
 
        $profPath = $profName;
83
 
    }
84
 
 
85
 
        # Only allow profiles with installed binaries unless specified with $allProfs
86
 
    if ( $allProfs != 1 && ! -f $profPath ) {
87
 
        return $badFileName;
88
 
    }
89
 
    if ( $profPath ) {
90
 
 
91
 
            if ( ($profPath !~ /^\./) &&
92
 
                 ($profPath !~ /.save$|.new$/) &&
93
 
                 ($profPath !~ /\s/) &&
94
 
                 ($profPath !~ /([!#-\@\w])\.$/) &&
95
 
                 (length($profPath) <= 128) ) {
96
 
 
97
 
                     $badFileName = 0;
98
 
            }
99
 
    }
100
 
 
101
 
    return $badFileName
102
 
}
103
 
 
104
 
 
105
 
# returns dot-format profile filenames
106
 
sub getProfList {
107
 
 
108
 
        my $args = shift;
109
 
        my $allProfs = $args->{'showall'} || 0;
110
 
 
111
 
    my @rawList = ();
112
 
    my @profList = ();
113
 
    my $error = undef;
114
 
 
115
 
    if ( opendir (MDIR, $profiledir) ) {
116
 
 
117
 
        @rawList = grep { ! /^\./  && ! /^lib(\d*)[\.|\/]ld/ && -f "$profiledir/$_" 
118
 
                            && ! /\.rpm(new|save)$/
119
 
 
120
 
                                } readdir(MDIR);
121
 
        close MDIR;
122
 
 
123
 
    } else {
124
 
                $error = "Couldn't open directory $profiledir.  Exiting.";
125
 
        ycp::y2error("$error");
126
 
        exit 1;
127
 
    }
128
 
 
129
 
        # Remove profiles without installed binaries by default 
130
 
        if ( $allProfs ne '1' ) {
131
 
                for my $prof (@rawList) {
132
 
                        if (! badFileName($prof,$allProfs)) {
133
 
                                push (@profList, $prof);
134
 
                        }
135
 
                }
136
 
        } else {
137
 
                @profList = @rawList;
138
 
        }
139
 
 
140
 
    return \@profList;
141
 
}
142
 
 
143
 
# returns both the dot-format and pathnames for profiles
144
 
sub getProfHash {
145
 
 
146
 
        my $args = shift;
147
 
    my $profList = getProfList($args);
148
 
    my @rawHash = ();
149
 
    my @profHash = ();
150
 
 
151
 
    for my $dotProf (@$profList) {
152
 
        if (open PROF, "<$profiledir/$dotProf") {
153
 
            while(<PROF>) {
154
 
                if (/^\/\w+/) {
155
 
                    my $prof = undef;
156
 
                    $prof->{'dot'} = $dotProf;
157
 
                    $prof->{'path'} = (split(/\s+[\{||flag]/, $_))[0];
158
 
                    push(@rawHash, $prof);
159
 
                    last;
160
 
                }
161
 
            }
162
 
 
163
 
            close PROF;
164
 
 
165
 
                    # Remove profiles without installed binaries by default
166
 
                    if ( $args->{'showall'} ne '1' ) {
167
 
                        for my $prof (@rawHash) {
168
 
                            if (! badFileName($prof->{'path'}, $args->{'showall'})) {
169
 
                                push (@profHash, $prof);
170
 
                            }
171
 
                        }
172
 
                    } else {
173
 
                                @profHash = @rawHash;
174
 
                        }
175
 
 
176
 
        } else {
177
 
            ycp::y2error("Couldn't open $profiledir/$dotProf");
178
 
            exit 1;
179
 
        }
180
 
    }
181
 
 
182
 
    return \@profHash;
183
 
}
184
 
 
185
 
sub getProfModes {
186
 
 
187
 
    my $profList = shift;
188
 
    my @profModeList = ();
189
 
 
190
 
    for my $profName (@$profList) {
191
 
 
192
 
        my $flag = undef;
193
 
 
194
 
        next if (-d $profName);
195
 
        next if ($profName =~ /^\./);
196
 
        next if ($profName =~ /.save$|.new$/);
197
 
 
198
 
        if ( open(PROFILE, "$profiledir/$profName")) {
199
 
 
200
 
            while(<PROFILE>) {
201
 
 
202
 
                if (m/^\s*\/\S+\s+(flags=\(.+\)\s+)*{\s*$/) {
203
 
                    $flag = $1;
204
 
                }
205
 
 
206
 
                if ($flag) {
207
 
                    $flag =~ s/flags=\((.+)\)/$1/;
208
 
                    $flag =~ s/\s//g;
209
 
                    last;            # only one profile except in /lib*/ld* which is a special case 
210
 
                } 
211
 
            }
212
 
 
213
 
            close(PROFILE);
214
 
 
215
 
        } else {
216
 
            ycp::y2milestone( "Couldn't open profile $profName for reading.");
217
 
        }
218
 
 
219
 
        if (! $flag) { $flag = 'enforce'};
220
 
 
221
 
        my $prof = {
222
 
            'name' => $profName,
223
 
            'mode' => $flag
224
 
        };
225
 
 
226
 
        # Don't add profile entries if the file doesn't exist
227
 
        if ( $prof->{'name'} ) {
228
 
                        push(@profModeList, $prof);
229
 
        }
230
 
 
231
 
    }
232
 
 
233
 
    return \@profModeList;
234
 
}
235
 
 
236
 
sub getProfStatus {
237
 
 
238
 
        my $args = shift;
239
 
    my $profList = getProfList($args);
240
 
    my $profModeList = getProfModes($profList);
241
 
 
242
 
    return $profModeList;
243
 
}
244
 
 
245
 
sub setProfMode {
246
 
 
247
 
    my $args = shift;
248
 
    my $ret = undef;
249
 
 
250
 
        my $profMode = undef;
251
 
 
252
 
        if ( $args->{'mode'} eq 'complain' ) {
253
 
                $profMode = 'complain';
254
 
        } else {
255
 
                $profMode = '';
256
 
        }
257
 
 
258
 
        # Change just the profile listed, if an associated binary exists 
259
 
    if ( $args->{'profile'} ) {
260
 
        my $profName = getProfPath("$args->{'profile'}");
261
 
 
262
 
        if ( badFileName($args->{'profile'}, $args->{'showall'} )) {
263
 
            ycp::y2milestone("Bad profile: $profName. Skipping.");
264
 
                } elsif ( $args->{'showall'} && $args->{'showall'} == 1 ) {
265
 
            setprofileflags("$profiledir/$args->{'profile'}", "$profMode");
266
 
                } else {
267
 
 
268
 
                if ($profMode eq 'complain') {
269
 
                    Immunix::SubDomain::complain("$profName");
270
 
                } else {
271
 
                    Immunix::SubDomain::enforce("$profName");
272
 
                }
273
 
                }
274
 
 
275
 
        # Change all profiles, regardless of whether the associated binary exists
276
 
    } elsif ( $args->{'showall'} && $args->{'showall'} == 1 ) {
277
 
 
278
 
        my $profHash = getProfHash($args);
279
 
        for my $prof (@$profHash) {
280
 
            setprofileflags("$profiledir/$prof->{'dot'}", "$profMode");
281
 
        }
282
 
 
283
 
        # Change all profiles with associated existing binaries
284
 
    } elsif ( $args->{'all'} == 1 ) {
285
 
 
286
 
        my $profHash = getProfHash($args);
287
 
 
288
 
        for my $prof (@$profHash) {
289
 
 
290
 
            if ( badFileName($prof->{'path'}), $args->{'showall'} ) {
291
 
                ycp::y2milestone("Bad profile: $prof->{'path'}. Skipping.");
292
 
            } elsif ($profMode eq 'complain') {
293
 
                Immunix::SubDomain::complain("$prof->{'path'}");
294
 
            } else {
295
 
                Immunix::SubDomain::enforce("$prof->{'path'}");
296
 
            }
297
 
        }
298
 
 
299
 
 
300
 
    } else {
301
 
        my $error = "ag_complain: Profile name needed for changing complain mode is missing.  Exiting.";
302
 
        ycp::y2milestone("$error");
303
 
        exit 1;
304
 
    }
305
 
 
306
 
    return;
307
 
}
308
 
 
309
 
# Main
310
 
################################################################################
311
 
while ( <STDIN> ) {
312
 
 
313
 
    my ($command, $path, $args) = ycp::ParseCommand ($_);
314
 
    if ($command && $path && $args) {
315
 
 
316
 
        my $db = undef;
317
 
 
318
 
                if ($args->{'mode'} && $args->{'mode'} =~ m/^(complain|enforce)$/  ) {
319
 
                        setProfMode($args);
320
 
        } else {
321
 
            $db = getProfStatus($args);
322
 
        }
323
 
 
324
 
        if ( defined($db) ) {
325
 
            ycp::Return( $db );
326
 
        } else {
327
 
            ycp::Return("1");
328
 
        }
329
 
 
330
 
    } else {
331
 
        my $error = "ag_complain: Unknown instruction or argument";
332
 
        ycp::y2milestone("$error");
333
 
        ycp::Return($error);
334
 
        exit 1;
335
 
    }
336
 
 
337
 
}
338
 
 
339
 
exit 0;
340